Read Embedded Newline characters with read (builtin) in KSH93

Hi Guys,

Happy New Year to you all!

I have a requirement to read an embedded new-line using KSH's read builtin.
Here is what I am trying to do:

run_sql "select guestid, address, email from guest" | while read id addr email
do
   ## Biz logic goes here
done

I can take care of any embedded spaces by escaping them with a '\' in the run_sql utility and read would parse the value correctly.
However, address field can have embedded new line characters. Is there an escape sequence I can use to encode any embedded newlines, so the read command would store the new-line character in 'addr' variable?
I have tried '\n', but read doesn't recognize that escape-sequence.

Is there an option in read to accept embedded newlines? Or is there another builtin that can be used for this purpose?

Any help would be appreciated!

Asking a line oriented tool to not be line oriented is tough, but if you know it is continued, say because of an escape character, why not read again and concatenate?

I can write an abstraction layer (say, a function called readx) around read and use it instead of using read directly in my main loop.

However, I am writing a framework to integrate database access into the shell and want a minimum number of new functions/utilities to be introduced for my developers.

If there is a shell trick that can solve my problem then it would be great. Otherwise I will have to work around by creating custom function/builtin for the purpose.

read -r in ksh93 will leave the \n as they are. You can then use echo (or printf) to translate them to the correct character:

$ echo 'Programmer\\ntest' | read -r line rest
$ set | grep line                             
line='Programmer\ntest'
$ line=$(echo $line)
$ set | grep line
line=$'Programmer\ntest'
1 Like

Hmm... this can be done. But it requires a step of post-processing the value after read, which I was trying to avoid. :slight_smile:
Seems like extra processing will be required to solve my problem. :frowning:

Suggest you write an sql program to output the fields to a file (not a pipe) in a more useable format. Maybe the whole process can be done in sql? Really depends what you are going to do with the data.

Well, how does the shell know which line feeds are real?

You might write a standard (local shared), postprocessing, sql tool (wrapper) for all to use, and make it encode embedded linefeeds in a printf friendly form, while escaping any printf metacharacters in the flow. It seems unlikely people will enter '\n' or '%' in their text, but with escapes, it would stay '\n' and '%'! It can trim and divert headers, counts, dividers and messages at the same time. It will be like JDBC/ODBC or ESQL, but crude and more work. Why not step up to a RDBMS tool or existing scripting extension for your RDBMS, sybperl or such?