How to Write Multiple Line String Using Bash with Variables

Multi-line string with extra space (preserved indentation)

Heredoc sounds more convenient for this purpose. It is used to send multiple commands to a command interpreter program like ex or cat

cat << EndOfMessage
This is line 1.
This is line 2.
Line 3.
EndOfMessage

The string after << indicates where to stop.

To send these lines to a file, use:

cat > $FILE <<- EOM
Line 1.
Line 2.
EOM

You could also store these lines to a variable:

read -r -d '' VAR << EOM
This is line 1.
This is line 2.
Line 3.
EOM

This stores the lines to the variable named VAR.

When printing, remember the quotes around the variable otherwise you won't see the newline characters.

echo "$VAR"

Even better, you can use indentation to make it stand out more in your code. This time just add a - after << to stop the tabs from appearing.

read -r -d '' VAR <<- EOM
This is line 1.
This is line 2.
Line 3.
EOM

But then you must use tabs, not spaces, for indentation in your code.

How to specify a multi-line shell variable?

Use read with a heredoc as shown below:

read -d '' sql << EOF
select c1, c2 from foo
where c1='something'
EOF

echo "$sql"

How to assign a multiple line value to a bash variable

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

How to write multiple line string using Bash with variables?

The syntax (<<<) and the command used (echo) is wrong.

Correct would be:

#!/bin/bash

kernel="2.6.39"
distro="xyz"
cat >/etc/myconfig.conf <<EOL
line 1, ${kernel}
line 2,
line 3, ${distro}
line 4 line
...
EOL

cat /etc/myconfig.conf

This construction is referred to as a Here Document and can be found in the Bash man pages under man --pager='less -p "\s*Here Documents"' bash.

Bash: split long string argument to multiple lines?

You can assign your string to a variable like this:

long_arg="my very long string\
which does not fit\
on the screen"

Then just use the variable:

mycommand "$long_arg"

Within double quotes, a newline preceded by a backslash is removed. Note that all the other white space in the string is significant, i.e. it will be present in the variable.

How to output a multiline string in Bash?

Here documents are often used for this purpose.

cat << EOF
usage: up [--level <n>| -n <levels>][--help][--version]

Report bugs to:
up home page:
EOF

They are supported in all Bourne-derived shells including all versions of Bash.

Substituting keyword in string with multi-line variable via sed

Introduction/Setup

sed is not necessarily the appropriate tool for this particular job. Consider the below options -- the samples for each of which expect the following setup:

# Run this before testing any of the code below
source='bar'
target='This string contains a target: <bar>'
solution='This has
multiple lines
and /slashes/ in the text'

...and each of which will emit the following output:

This string contains a target: <This has
multiple lines
and /slashes/ in the text>

Note that with sed, you would need to choose a delimiter that isn't used for the expression (thus, with s/foo/bar/, neither foo nor bar can contain a /); the below answers both avoid this limitation.


Shell-Builtin Parameter Expansion

The shell can perform the relevant substitution with only built-in string manipulation functionality:

result=${target//$source/$solution}
echo "$result"

Perl One-Liners As A sed Alternative

For longer input strings where the shell's built-in matching is inappropriate, you might also consider a perl one-liner, as described in BashFAQ #21:

in="$source" out="$solution" perl -pe 's/\Q$ENV{"in"}/$ENV{"out"}/g' <<<"$target"


Related Topics



Leave a reply



Submit