35

I want to assign the grep result to a variable for further use:

lines=$(cat abc.txt | grep "hello")

but seems newline characters are removed in the result, when I do

echo $lines

only one line is printed. How can I preserve newline characters, so when I echo $lines, it generates the same result as cat abc.txt | grep "hello" does.

Dagang
  • 24,586
  • 26
  • 88
  • 133

2 Answers2

64

You want to say

echo "$lines"

instead of

echo $lines

To elaborate:

echo $lines means "Form a new command by replacing $lines with the contents of the variable named lines, splitting it up on whitespace to form zero or more new arguments to the echo command. For example:

lines='1 2 3'
echo $lines   # equivalent to "echo 1 2 3"
lines='1   2   3'
echo $lines   # also equivalent to "echo 1 2 3"
lines="1
2
3"
echo $lines   # also equivalent to "echo 1 2 3"

All these examples are equivalent, because the shell ignores the specific kind of whitespace between the individual words stored in the variable lines. Actually, to be more precise, the shell splits the contents of the variable on the characters of the special IFS (Internal Field Separator) variable, which defaults (at least on my version of bash) to the three characters space, tab, and newline.

echo "$lines", on the other hand, means to form a single new argument from the exact value of the variable lines.

For more details, see the "Expansion" and "Word Splitting" sections of the bash manual page.

Sean
  • 29,130
  • 4
  • 80
  • 105
2

Using the Windows port for grep (not the original question, I kow and not applicable to *nix). I found that -U solved the problem nicely.

From the --help:

-U, --binary do not strip CR characters at EOL (MSDOS)

  • 1
    It works. Thanks @Haggisbreath. using -U logs getting printed with new line. grep command is... electron app.js | grep --line-buffered -i -e "error" -U | tee logs.txt – Gaurav Aug 10 '17 at 12:44