Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

When I do

str="Hello World\n===========\n"

I get the \n printed out too. How can I have newlines then?

share|improve this question
    
While the answers here are great, in reality I think you'd be better off using an array for this sort of thing most of the time. –  evilsoup Jun 10 '13 at 8:49

7 Answers 7

up vote 25 down vote accepted

In bash you can use the syntax

str=$'Hello World\n===========\n'

Single quotes preceded by a $ is a new syntax that allows to insert escape sequences in strings.

Also printf builtin allows to save the resulting output to a variable

printf -v str 'Hello World\n===========\n'

Both solutions do not require a subshell.

If in the following you need to print the string, you should use double quotes, like in the following example:

echo "$str"

because when you print the string without quotes, newline are converted to spaces.

share|improve this answer
    
What is the syntax str=$'Hello World\n===========\n' called? variable substitution? –  zengr Aug 10 '13 at 0:28
    
@zengr: It's called ANSI-C quoting, and it's also supported in zsh and ksh; however, it is NOT POSIX-compliant. –  mklement0 Jul 8 at 14:46

You can put literal newlines within single quotes (in any Bourne/POSIX-style shell).

str='Hello World
===========
'

For a multiline string, here documents are often convenient. The string is fed as input to a command.

mycommand <<'EOF'
Hello World
===========
EOF

If you want to store the string in a variable, use the cat command in a command substitution. The newline character(s) at the end of the string will be stripped by the command substitution. If you want to retain the final newlines, put a stopper at the end and strip it away afterward. In POSIX-compliant shells, you can write str=$(cat <<'EOF'); str=${str%a} followed by the heredoc proper, but bash requires the heredoc to appear before the closing parenthesis.

str=$(cat <<'EOF'
Hello World
===========
a
EOF
); str=${str%a}

In ksh, bash and zsh, you can use the $'…' quoted form to expand backslash escapes inside the quotes.

str=$'Hello World\n===========\n'
share|improve this answer
    
I'm using GNU bash 4.1.5, and str=$(cat <<'EOF') doesn't work as-is.. The ) needs to be placed on the next line after the end-of-doc EOF.. but even so, it loses the trailing newline due to Command Substitution. –  Peter.O Sep 3 '11 at 16:49
    
@fred Good points, I've explained about the trailing newlines and shown code that works in bash. I think it's a bug in bash, though to be honest upon rereading the POSIX spec I find it unclear that the behavior is mandated when the << is inside a command substitution and the heredoc isn't. –  Gilles Sep 4 '11 at 17:01
    
Great stuff; to preserve trailing (and leading) \n instances in bash when capturing a here-doc in a variable, consider IFS= read -r -d '' str <<'EOF'... as an alternative to the stopper approach (see my answer). –  mklement0 Jul 8 at 15:29

Are you using "echo"? Try "echo -e".

echo -e "Hello World\n===========\n"
share|improve this answer
1  
BTW. You don't need the final \n, because echo will automatically add one, unless you specify -n. (However, the main brunt of the question, is how to get these newlines into a variable). –  Peter.O Sep 3 '11 at 8:48
    
+1 Of all the solutions, this one is the most direct and simplest. –  Hai Vu Sep 3 '11 at 16:11
    
echo -e doesn't work in OS X –  Greg Krsak Feb 4 at 20:21
1  
@GregKrsak: In bash, echo -e does work on OS X - that's because echo is a bash builtin (rather than an external executable) and that builtin does support -e. (As a builtin, it should work on all platforms that bash runs on; incidentally, echo -e works in ksh and zsh too). By contrast, however, the external echo utility on OS X - /bin/echo - indeed does not support -e. –  mklement0 Jul 8 at 14:54
    
Ah, thanks for the correction. –  Greg Krsak Jul 8 at 21:08

If you need newlines in your script many times you could declare a global variable holding a newline. That way you can use it in double-quoted strings (variable expansions).

NL=$'\n'
str="Hello World${NL} and here is a variable $PATH ===========${NL}"
share|improve this answer
    
Why would $'' require a subshell? –  Mat Jun 10 '13 at 7:43
    
Sorry, I misread an answer. –  pihentagy Jun 10 '13 at 11:19

From all discussion, here is the simplest way for me:

bash$ str="Hello World
==========="
bash$ echo "$str"
Hello World
===========

The echo command must use double quotes.

share|improve this answer

To complement the great existing answers:

If you're using bash and you prefer using actual newlines for readability, read is another option for capturing a here-doc in a variable.

With trailing (and leading) \n instances REMOVED ($IFS set to \n):

IFS=$'\n' read -r -d '' str <<'EOF'
Hello World
===========
EOF

# Test
printf %q "$str" # -> $'Hello World\n==========='

With trailing (and leading) \n instances PRESERVED ($IFS set to empty):

IFS= read -r -d '' str <<'EOF'
Hello World
===========
EOF

# Test
printf %q "$str" # -> $'Hello World\n===========\n'
  • -r ensures that read doesn't interpret the input (by default, it would treat backslashes special)
  • -d '' sets the "record" delimiter to an empty string, causing read to read the entire input at once (instead of just a single line).
  • By setting the set of internal field separator characters, $IFS:
    • to an empty string,the entire here-doc is read as is.
    • to $'\n' (an newline expressed as an ANSI-C quoted string), leading and trailing \n instances are automatically trimmed.
  • Note that prepending IFS=... directly to the read command means that the assignment is in effect during that command only, so there is no need to restore the previous value.
share|improve this answer

you need to do it this way:

STR=$(echo -ne "Hello World\n===========\n")

Update:

As Fred pointed it out, this way you will loose trailing "\n". To assign variable with backslash sequences expanded, do:

STR=$'Hello World\n===========\n\n'

let's test it:

echo "[[$STR]]"

gives us now:

[[Hello World
===========

]]

Note, that $'' is different than $"". The second does translation according to current locale. For deital see QUOTING section in man bash.

share|improve this answer
1  
The Command Substituion will cause $STR to lose the trailing '\n'... and BTW, echo -e "Hello World\n=======" produces the trailing \n, as does your echo... - For more info on command substitution, see Why does shell Command Substitution gobble up a trailing newline char? –  Peter.O Sep 3 '11 at 8:33
    
@fred: very good comment. +1. I will update answer to cever this issue. –  Michał Šrajer Sep 3 '11 at 10:01

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.