in Ksh, why does the last (empty) line of my multi-line string disappears when saving it in a variable?

153 views Asked by At

While implementing a script, I am facing the following issue : when putting the multi-line result of a command into a variable, it seems the last (empty) line of my multi-line string disappear.

This line is "empty", but however, I can not lose the carriage return it contains (because I am concatenating blocks of code saved in DB and containing "\n" character into a human-readable string... If I lose some of the "\n", I will lose a part of my code indentation)

Here is the code to illustrate my issue :

test="A

B
";
test2=`echo "$test"`;
echo "||$test2||";

This returns

||A

B||

while I was expecting :

||A

B
||

--> the last (empty) line has disappeared... and a carriage return is thus missing in my human-readable code.

This issue only occurs when the last line of my multi-line string is empty...

Do you know

  • Why this last line disappears ?
  • How I can ensure my last empty line is saved in my multi-line string variable ?

Note that I can of course not use the easiest solution

test2="$test";

because the complete process is rather :

test="^A\n\nB\n^"
test2="`echo "$test" | sed -e 's/\^//g'`";

but I tried to simplify the issue the most I could.

2

There are 2 answers

7
Charles Duffy On BEST ANSWER

Command substitutions always trim trailing newlines -- that's in accordance with design and specification. If you don't want that, you can append a fixed sigil character to your output and trim it, such that the newlines you want to preserve are before the sigil:

test="A

B
"
test_wip=$(printf '%sEND' "$test")
test2=${test_wip%END}
5
markp-fuso On

Instead of trying to work around the issues that arise from assigning the output from echo to a variable (eg, stripping of trailing \n's), consider using ksh's built in string processing in this case, eg:

$ test="^A\n\nB\n^"
$ test2="${test//^}"
$ echo "||${test2}||"
||A

B
||
  • //^ : remove all ^ characters