I'm a bit confused with printing a variable that contain a new line symbol in bash.
var="Age:\n20\ncolor:\nred"
echo -e $var
Age:
20
color:
red
This is working, but a lot of people say that echo with options is not portable and it is better to use printf.
I never used prinf. According to manuals to emitate echo command:
printf '%s\n' "$var"
Age:\n20\ncoloe:\nred
But this doesn't parse \n inside variable. manuals usually have this example:
printf "Surname: %s\nName: %s\n" "$SURNAME" "$LASTNAME"
But it's not my case and from my point of view it not comfortable to use. I found out simply by typing that I can use this:
printf "$var\n"
Is it portable? If I then pass $var to a mail command will it save new line breaks?
printf "$var\n" | mail -s subj [email protected]
Printing Newline in Bash The most common way is to use the echo command. However, the printf command also works fine. Using the backslash character for newline “\n” is the conventional way. However, it's also possible to denote newlines using the “$” sign.
Using \x0A 0A in hexadecimal (10 in Decimal) is the ASCII value of new line character, we can use \x0A anywhere in the printf() statement to print text in new line.
Note echo adds \n at the end of each sentence by default whether we use -e or not. The -e option may not work in all systems and versions. Some versions of echo may even print -e as part of their output.
printf
's %b
format specifier was meant specifically to replace echo -e
(actually, the XSI extension to echo
which calls for special interpretation of the arguments by default. -e
was never specified and is disallowed by POSIX.), and is identical in virtually every way including a few differences from $'...'
and the format string argument to printf
.
$ ( var='Age:\n20\ncolor:\nred'; printf '%b\n' "$var" )
Age:
20
color:
red
You should generally avoid expanding variables into the format string unless your program controls the exact value and it is intended specifically to be a format string. Your last example in particular has the potential to be quite dangerous in Bash due to printf
's -v
option.
# Bad!
var='-v_[$(echo "oops, arbitrary code execution" >&2)0]'
printf "$var" foo
It is usually good practice to avoid %b
unless you have a special portability requirement. Storing the escape codes in a variable instead of the literal data violates principles of separation of code and data. There are contexts in which this is ok, but it is usually better to assign the the value using $'...'
quoting, which is specified for the next version of POSIX, and has long been available in Bash and most ksh flavours.
x=$'foo\nbar'; printf '%s\n' "$x" # Good
x=(foo bar); printf '%s\n' "${x[@]}" # Also good (depending on the goal)
x='foo\nbar'; printf '%b\n' "$x" # Ok, especially for compatibility
x='foo\nbar'; printf -- "$x" # Avoid if possible, without specific reason
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With