1

It seems that Bash converts LF to LFCR. Indeed, here is an example bellow that describes that:

text=$(echo -e "foo\nbar\ntir")

When setting IFS to the LF end of line:

IFS=$(echo -e "\n")

the \n in the string text is not interpreted such as bellow:

for w in $text ; do echo ${w}';' ; done

Output:

foo
bar
tir;

Here the character ";" used as a marker shows that $text contains only one element and so \n is not interpreted although it was set as the IFS.

But now, while setting IFS to the LFCR end of line:

IFS=$(echo -e "\n\r")

the output of the previous command turns into:

foo;
bar;
tir;

The marker ";" shows that $text contains three elements and thereby \n in $text has been interpreted as a \n\r (LFCR) set as the IFS.

So, why does Bash seems convert LF to LFCR? If it does not, what is the underlying explanation please?

moth
  • 345
  • 1
  • 13
  • You aren't trying to avoid the proper use of an array, are you? `text=(foo bar tir); for w in "${text[@]}"; do echo "$w;"; done`. – chepner May 16 '18 at 13:09

1 Answers1

3

$IFS is actually being set to an empty string.

$ IFS=$(echo -e "\n")
$ echo "[$IFS]"
[]

When $(...) captures output it removes trailing newlines. You can set $IFS to a newline by using $'...', shell syntax that interprets escape sequences while avoiding the trimming problem.

$ IFS=$'\n'
$ echo "[$IFS]"
[
]
$ text=$'foo\nbar\nbaz\n'
$ printf '%s;\n' $text
foo;
bar;
baz;
John Kugelman
  • 349,597
  • 67
  • 533
  • 578