15

I have a variable FOO with me that needs to be assigned with a value that will be multiple lines. Something like this,

FOO="This is line 1
     This is line 2
     This is line 3"

So when I print the value of FOO it should give the following output.

echo $FOO
output:
This is line 1
This is line 2
This is line 3

Furthermore, the number of lines will be decided dynamically as I will initialize it using a loop.

The answers that have been shown in the other question using mainly read -d is not suitable for me as I am doing intensive string operations and the code format is also important.

molecule
  • 1,027
  • 1
  • 14
  • 27

3 Answers3

35

Don't indent the lines or you'll get extra spaces. Use quotes when you expand "$FOO" to ensure the newlines are preserved.

$ FOO="This is line 1 
This is line 2   
This is line 3"
$ echo "$FOO"
This is line 1
This is line 2
This is line 3

Another way is to use \n escape sequences. They're interpreted inside of $'...' strings.

$ FOO=$'This is line 1\nThis is line 2\nThis is line 3'
$ echo "$FOO"

A third way is to store the characters \ and n, and then have echo -e interpret the escape sequences. It's a subtle difference. The important part is that \n isn't interpreted inside of regular quotes.

$ FOO='This is line 1\nThis is line 2\nThis is line 3'
$ echo -e "$FOO"
This is line 1
This is line 2
This is line 3

You can see the distinction I'm making if you remove the -e option and have echo print the raw string without interpreting anything.

$ echo "$FOO"
This is line 1\nThis is line 2\nThis is line 3
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • Hi John, your example code works for me! However, in the first example above, when I echo the variable with ```echo $FOO``` without putting $FOO between the quotation marks, the output is on the same line. Do you know why? I'm using GNU bash, version 4.3.11(1)-release on Ubuntu 14.04. – yaobin Oct 30 '17 at 16:59
  • That's what happens when you don't have quotes. The value is subject to *word splitting* and *glob expansion*. Instead of `echo` being told to print one argument with embedded newlines, each word of `$FOO` becomes a separate argument with no newlines. It's as if you wrote `echo This is line 1 This is line 2 This is line 3`. Bottom line: always quote variable expansions unless you actually want it to be subject to word splitting and globbing (rare). – John Kugelman Oct 30 '17 at 18:07
4

When you initialize FOO you should use line breaks: \n.

FOO="This is line 1\nThis is line 2\nThis is line 3"

Then use echo -e to output FOO.

It is important to note that \n inside "..." is NOT a line break, but literal \ , followed by literal n. It is only when interpreted by echo -e that this literal sequence is converted to a newline character. — wise words from mklement0


#!/bin/bash

FOO="This is line 1\nThis is line 2\nThis is line 3"
echo -e $FOO

Output:
This is line 1
This is line 2
This is line 3
Community
  • 1
  • 1
Jonny Henly
  • 4,023
  • 4
  • 26
  • 43
  • Its giving output as `-e This is line 1 This is line 2 This is line 3` – Juned Jun 29 '16 at 05:03
  • 2
    @juned You need a version of `echo` which supports `-e`. Bash's built-in echo command does, as does GNU's `/bin/echo` binary. – John Kugelman Jun 29 '16 at 05:06
  • No that worked when I ran script with `./script.sh` but with `sh scripname` it ddin't – Juned Jun 29 '16 at 05:07
  • 1
    Don't run scripts with `sh script.sh`. It overrides the interpreter the script wants, instead using plain `sh`. Type `./script.sh` to ensure the correct interpreter is used. – John Kugelman Jun 29 '16 at 05:09
  • 1
    Hope you don't mind that I added your comment to my answer @mklement0 , feel free to edit it to your liking. – Jonny Henly Jun 29 '16 at 05:26
0

You could also store the lines to a variable using read lines:

$ read -r -d '' FOO << EOF
This is line 1
This is line 2
This is line 3
EOF

To see the newline on printing use quotes around the variable: (echo "$FOO" not echo $FOO)

$ echo "$FOO"
This is line 1
This is line 2
This is line 3
eQ19
  • 9,880
  • 3
  • 65
  • 77