How to assign a string value to a variable over multiple lines while indented?

Here the issue is that you are surrounding the variable with double quotes (""). Remove it and things will work fine.

    VAR="This displays with \
    extra spaces."
    echo ${VAR}

Output

 This displays with extra spaces.

Here the issue is that double quoting a variable preserves all white space characters. This can be used in case if you explicitly need it.

For example,

$ echo "Hello     World    ........ ...            ...."

will print

Hello     World    ........ ...            ....

And on removing quotes, its different

$ echo Hello     World    ........ ...            ....
Hello World ........ ... ....

Here the Bash removes extra spaces in the text because in the first case the entire text is taken as a "single" argument and thus preserving extra spaces. But in the second case echo command receives the text as 5 arguments.

Quoting a variable will also be helpful while passing arguments to commands.

In the below command, echo only gets single argument as "Hello World"

$ variable="Hello World"
$ echo "$variable"

But in case of the below scenario echo gets two arguments as Hello and World

$ variable="Hello World"
$ echo $variable

The solutions given by esuoxu and Mickaël Bucas are the common and more portable ways of doing this.

Here are a few bash solutions (some of which should also work in other shells, like zsh). Firstly with the += append operator (which works in a slightly different way for each of an integer variable, a regular variable and an array).

text="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod "
text+="tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, "
text+="quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea ..." 

If you want newlines (or other whitespace/escapes) in the text, use $'' quoting instead:

text=$'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\n'
text+=$'...'

Next, using printf -v to assign a formatted value to a variable

printf -v text "%s" "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed " \
                    "do eiusmod empor incididunt ut labore et dolore magna aliqua. "\
                    "Ut enim ad minim veniam ..."

The trick here is that there are more arguments than format specifiers, so unlike most printf functions, the bash one reuses the format string until it runs out. You can put a \n within the format string, or use $'', (or both) to deal with whitespace.

Next, using an array:

text=("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod "
      "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, "
      "quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea ..." )

You can also use += to build the text up line by line (note the ()):

text+=("post script")

Here though, you must remember to "flatten" the array if you want the entire text content in one go

echo "$text"      # only outputs index [0], the first line
echo "${text[*]}" # output complete text (joined by first character of IFS)

(integer indexed arrays are implicitly sorted, unlike associative arrays) This gives you slightly more flexibility since you can manipulate lines and even slice and dice if needed.

Finally, using read or readarray and a "here-document":

read -r -d '' text <<-"EOT"
        Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
        tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, 
        quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea ...
EOT

readarray -t textarray <<-"EOT"
        Lorem [...]
EOT  

The here-document form of <<- means all leading hard tabs are removed from the input, so you must use tabs to indent your text. Quotes around "EOT" prevent shell expansion features, so the input is used verbatim. With read it uses NUL byte delimited input, so that it will read the newline delimited text in one go. With readarray (aka mapfile, available since bash-4.0) it reads into an array, and -t strips newlines on each line.


There is a special heredoc syntax that removes tabs at the beginning of all lines : "<<-" (notice the dash added)

http://tldp.org/LDP/abs/html/here-docs.html

Example 19-4. Multi-line message, with tabs suppressed

You can use it like this :

v="$(cat <<-EOF
    A
        B
    C
EOF
)"
echo "$v"

Result :

A
B
C

It works only with tabs, not spaces.

Tags:

Variable