Why does bash remove \n in $(cat file)?

If you use

echo "$(cat input.txt)"

it will work correctly.

Probably the input of echo is separated by newlines, and it will handle it as separate commands, so the result will be without newlines.


Quoted from bash manual page, section Command Substitution:

Embedded newlines are not deleted, but they may be removed during word splitting.

A little further, same section :

If the substitution appears within double quotes, word splitting and pathname expansion are not performed on the results.

That's why echo "$(cat /etc/passwd)" works.

Additionally, one should be aware, that command substitution by POSIX specifications removes trailing newlines:

$ echo "$(printf "one\ntwo\n\n\n")"
one
two

Thus, outputting a file via $(cat file.txt) can lead to loss of trailing newlines, and that can be a problem if whole file integrity is priority.


You can preserve newlines, for example by setting IFS to empty:

$ IFS=
$ a=$(cat links.txt)
$ echo "$a"
link1
link2
link3