89
#!/usr/local/bin/bash
out=`grep apache README`
echo $out;

Usually grep shows each match on a separate line when run on the command line. However, in the above scripts, the newline separating each match disappears. Does anyone know how the newline can be preserved?

  • possible duplicate of [I just assigned a variable, but echo $variable shows something else](http://stackoverflow.com/questions/29378566/i-just-assigned-a-variable-but-echo-variable-shows-something-else) – that other guy Mar 31 '15 at 21:28
  • It's more a duplicate of [Capturing multiple line output to a bash variable](http://stackoverflow.com/questions/613572/capturing-multiple-line-output-to-a-bash-variable) – Renato Apr 23 '15 at 15:53

4 Answers4

117

You're not losing it in the assignment but in the echo. You can see this clearly if you:

echo "${out}"

You'll see a similar effect with the following script:

x="Hello,
I
am
a
string
with
newlines"
echo "====="
echo ${x}
echo "====="
echo "${x}"
echo "====="

which outputs:

=====
Hello, I am a string with newlines
=====
Hello,
I
am
a
string
with
newlines
=====

And, irrelevant to your question but I'd like to mention it anyway, I prefer to use the $() construct rather than backticks, just for the added benefit of being able to nest commands. So your script line becomes:

out=$(grep apache README)

Now that may not look any different (and it isn't) but it makes possible more complex commands like:

lines_with_nine=$(grep $(expr 7 + 2) inputfile)
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • 2
    I didn't know you could do that with $()... learn something new all the time here. – Tanj Apr 16 '09 at 02:18
  • 1
    You can do math without using expr. Just use double-parens: $((7 + 2)) – Barry Brown Apr 16 '09 at 02:23
  • Actually I might try that with all my answers from now on - append a (not always totally) relevant snippet for the education of the swarm :-) – paxdiablo Apr 16 '09 at 02:24
  • Good point, Barry, but it was just an example of nesting - my example-generating skills appear to have deteriorated with age (and/or alcohol :-). – paxdiablo Apr 16 '09 at 02:25
  • I just found out about the $(()) thing, myself. – Barry Brown Apr 16 '09 at 05:43
  • You write "You're not losing it in the assignment but in the echo." <-- I agree he's not losing it in the assignment, but are you sure he's losing it in the echo? From what I understand, https://www.gnu.org/software/bash/manual/html_node/Word-Splitting.html after a variable is expanded, then if it's not double quoted, word splitting occurs, and then(when IFS is unset or default), the new lines become spaces. Then echo just sees that. Just as printf would see that. – barlop May 11 '20 at 01:37
37

Put $out in quotes:

#!/usr/local/bin/bash
out=`grep apache README`
echo "$out";
Pesto
  • 23,810
  • 2
  • 71
  • 76
20

Quoting variables in bash preserves the whitespace.

For instance:

#!/bin/bash
var1="A B  C   D"
echo $var1   # A B C D
echo "$var1" # A B  C   D

since newlines are whitespace they get "removed"

Tanj
  • 1,354
  • 1
  • 15
  • 25
2

Combining other answers into a one liner:

echo "($(grep apache README))"
paragbaxi
  • 3,965
  • 8
  • 44
  • 58