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
Bash Script; How to Use Vars and Funcs Defined After Command
How to Replace Just One Newline Between > and < in Unix
Check Free Disk Space for Current Partition in Bash
Difference Between Netstat and Ss in Linux
Setting Node_Env for Node.Js + Expressjs Application as a Daemon Under Ubuntu
Tmux: Hangs and Do Not Load, and Do Not Respond to Any Option Command
Kernel Stack for Linux Process
Lowering Linux Kernel Timer Frequency
Find and Remove a Line in Multiple Files
Excluding Directory When Creating a .Tar.Gz File
How to Learn the Structure of Linux Wireless Drivers (Mac80211)
In Screen, How to Send a Command to All Virtual Terminal Windows Within a Single Screen Session
How to View Log Files in Linux and Apply Custom Filters While Viewing