This BASH script works as expected. I have a variable ($foo) that contains lines of data, I tell bash to separate at new lines, and I loop through the variable.

#!/bin/bash 

foo="
Original Line1
Original Line2
Original Line3
"

IFS=$'\n'

for line in $foo
do
  echo $line
done

As expected, the data is on it's own line.

Original Line1
Original Line2
Original Line3

I add this line to the script, to replace the text "Line2" with "EXAMPLE" in the $foo variable.

foo=$( echo $foo | sed "s|Line2|EXAMPLE|" )

When I run the script, the data is no longer separated on it's own line, and instead prints on a single line. I am not sure how I can replace values in a variable and retain new lines.

Original Line1 Original EXAMPLE Original Line3
  • 1
    Quote the variable: echo "$foo" | ... . See Why does my shell script choke on whitespace or other special characters? – steeldriver Oct 11 at 12:24
  • Nice - thanks @steeldriver. That works like a charm. If you want to post this as an answer, I'm happy to accept this as the solution. Thanks also for the link to the post that describes this behavior. Very nice. – JeremyCanfield Oct 11 at 12:34
  • you might be happier with arrays: foo=("Original Line1" "Original Line 2" ...) – Jeff Schaller Oct 11 at 12:48
  • Hey @JeffSchaller - Thanks for mentioning using an array. I'll keep that in mind as I work through the actual script. I can probably do either a variable or array. Currently, the real script is storing values in variables, hence why I was looking at doing this with variables. – JeremyCanfield Oct 12 at 2:03
  • Looping over a list of things is much more natural in an array. No IFS concerns, for one. – Jeff Schaller Oct 12 at 2:06
up vote 1 down vote accepted

Your unquoted variable $foo is subject to word splitting by the shell, as explained in detail in Why does my shell script choke on whitespace or other special characters?.

Using quotes will prevent that:

echo "$foo" | sed "s|Line2|EXAMPLE|"

Note that you don't really need sed for such a simple replacement - you could use shell substitution

foo="${foo/Line2/EXAMPLE}"

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.