If I have the file input.txt
containing:
hello
world
!
Then executing the bash command echo $(cat input.txt)
will output this:
hello world !
Why and how can I fix it to output exactly what is in the file how it is in the file?
If I have the file input.txt
containing:
hello
world
!
Then executing the bash command echo $(cat input.txt)
will output this:
hello world !
Why and how can I fix it to output exactly what is in the file how it is in the 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
echo "$(date) something"
stripping away the trailing newline from date's output, making that echo output the date and "something" on the same line. If you need to store a file or command output "as is", use mapfile (help mapfile
),read -rd ''
or a while read-loop. – geirha Apr 14 '12 at 08:26