Generally, we associate strings with a single line. But there can be occasions when the string might go beyond the traditional single line and stretch over multiple lines. In this tutorial, we will understand how Bash processes these multiline strings.
2. Multiline string using Heredoc
Heredoc is generally brought to use when we need to pass more than one input line to a command. We are free to give the heredoc any name.
[COMMAND] <<[-] 'DELIMITER' Line 1 Line 2 … … Line N DELIMITER
#!/bin/bash cat << Multi We have a multiline string. We have line number two now. Line 3 follows. Multi cat << X We have a multiline string. We have line number two now. Line 3 follows. X
The << symbol acts as the redirection operator for forwarding a heredoc to the cat command. Any character or word that won't appear in the body can act as the delimiter. The delimiter in the last line indicates the end of heredoc. Here, we have used two different delimiters, one called Multi and the other X. The cat command will read the heredoc until it encounters the last line delimiter. It then writes the contents of the heredoc to the standard output.
3. Multiline string in one line
Bash has never been stringent. On the contrary, we will always come across multiple ways of implementing the same scenario in Bash. Storing and displaying a multi line string in one line is no different.
3.1. Using echo
The echo command is very popular and widely used. Its sole purpose is to display the results on the terminal. In our case, we want to display multiple lines using a single echo command. Here’s how we can achieve this.
text="Line1\nLine2\nLine3\nLineN" echo -e $text
We have taken multiple lines and saved it in a variable named text. We have tweaked a little as we want to save these lines as a single line. We know \n denotes line breaks. Henceforth, we have concatenated every line in a single line using the line break notation. To display this output as multiple lines, even though they are saved as a single line, we just need to supply the -e option with the echo command. This option is meant to print on the same line. When it starts printing it will print Line1 after which it will encounter the \n symbol. It will be forced to give a line break. This process will continue till the last character gets printed.
3.2. Using printf
Printf is another ideal command to achieve the same task. It works the same way as its C programming language counterpart.
printf "%s\n" "line 1" "line 2" "line N"
The printf command converts, formats, and writes the supplied input to the standard output. We have supplied the %s specifier since the output has to be a string. The notation \n is the sequence for a newline character. It directs printf to begin a new line and continue the output from there. In our case it will print line 1 give a line break, print line 2 give another line break and then print line N.
4. Store multiple line string
We know Bash can redirect the output to a file or store it in a variable. Storing multiple lines is no different.
#!/bin/bash filename=store.txt cat > $filename << EOF Line 1 Line 2 Line N EOF
We are using the heredoc redirection technique to have a multi-line input. Cat command is supposed to display the output on the terminal. However, since we have used the ">" symbol we are effectively making cat output the contents to the filename variable. Thus, the multi line string will get stored in the file store.txt.
#!/bin/bash var1=$(cat << END This is line one. This is line two. This is line three. END ) echo "$var1" read -r -d '' var2<< EOF Line 1 Line 2 Line N EOF echo "$var2"
Again, we have multiple ways of storing a multiline string in a variable. We have to make a rule of the thumb that whenever we want multiple lines as an input, we will have to use the heredoc in some capacity with minor tweaking to get the desired result. In our example, we have considered two approaches to store the output in a variable. In both cases, we have used the heredoc. In the first approach, we have surrounded the entire statement by the $() symbol. We have declared a variable and equated it to this. In the second case as well, we are reading using the read command and storing the result in var2 until the EOF gets read.
When printing the value held in the variable, we have to surround the variable with quotes. Failing to do so will not give the newline characters.
- We need heredoc to pass more than one input line to a command.
- With echo and printf command we can have multiline strings in single lines.
- The result of multiline strings can be stored in a file as well as a variable.