Advertisement
Advertisement


How can I have a newline in a string in sh?


Question

This

STR="Hello\nWorld"
echo $STR

produces as output

Hello\nWorld

instead of

Hello
World

What should I do to have a newline in a string?

Note: This question is not about echo. I'm aware of echo -e, but I'm looking for a solution that allows passing a string (which includes a newline) as an argument to other commands that do not have a similar option to interpret \n's as newlines.

2015/06/05
1
349
6/5/2015 7:20:11 AM

Accepted Answer

The solution is to use $'string', for example:

$ STR=$'Hello\nWorld'
$ echo "$STR" # quotes are required here!
Hello
World

Here is an excerpt from the Bash manual page:

   Words of the form $'string' are treated specially.  The word expands to
   string, with backslash-escaped characters replaced as specified by  the
   ANSI  C  standard.  Backslash escape sequences, if present, are decoded
   as follows:
          \a     alert (bell)
          \b     backspace
          \e
          \E     an escape character
          \f     form feed
          \n     new line
          \r     carriage return
          \t     horizontal tab
          \v     vertical tab
          \\     backslash
          \'     single quote
          \"     double quote
          \nnn   the eight-bit character whose value is  the  octal  value
                 nnn (one to three digits)
          \xHH   the  eight-bit  character  whose value is the hexadecimal
                 value HH (one or two hex digits)
          \cx    a control-x character

   The expanded result is single-quoted, as if the  dollar  sign  had  not
   been present.

   A double-quoted string preceded by a dollar sign ($"string") will cause
   the string to be translated according to the current  locale.   If  the
   current  locale  is  C  or  POSIX,  the dollar sign is ignored.  If the
   string is translated and replaced, the replacement is double-quoted.
2020/01/03
366
1/3/2020 9:23:17 PM

Echo is so nineties and so fraught with perils that its use should result in core dumps no less than 4GB. Seriously, echo's problems were the reason why the Unix Standardization process finally invented the printf utility, doing away with all the problems.

So to get a newline in a string:

FOO="hello
world"
BAR=$(printf "hello\nworld\n") # Alternative; note: final newline is deleted
printf '<%s>\n' "$FOO"
printf '<%s>\n' "$BAR"

There! No SYSV vs BSD echo madness, everything gets neatly printed and fully portable support for C escape sequences. Everybody please use printf now and never look back.

2018/05/20

What I did based on the other answers was

NEWLINE=$'\n'
my_var="__between eggs and bacon__"
echo "spam${NEWLINE}eggs${my_var}bacon${NEWLINE}knight"

# which outputs:
spam
eggs__between eggs and bacon__bacon
knight
2012/12/01

The problem isn't with the shell. The problem is actually with the echo command itself, and the lack of double quotes around the variable interpolation. You can try using echo -e but that isn't supported on all platforms, and one of the reasons printf is now recommended for portability.

You can also try and insert the newline directly into your shell script (if a script is what you're writing) so it looks like...

#!/bin/sh
echo "Hello
World"
#EOF

or equivalently

#!/bin/sh
string="Hello
World"
echo "$string"  # note double quotes!
2015/12/18

I find the -e flag elegant and straight forward

bash$ STR="Hello\nWorld"

bash$ echo -e $STR
Hello
World

If the string is the output of another command, I just use quotes

indexes_diff=$(git diff index.yaml)
echo "$indexes_diff"
2019/03/28

  1. The only simple alternative is to actually type a new line in the variable:

    $ STR='new
    line'
    $ printf '%s' "$STR"
    new
    line
    

    Yes, that means writing Enter where needed in the code.

  2. There are several equivalents to a new line character.

    \n           ### A common way to represent a new line character.
    \012         ### Octal value of a new line character.
    \x0A         ### Hexadecimal value of a new line character.
    

    But all those require "an interpretation" by some tool (POSIX printf):

    echo -e "new\nline"           ### on POSIX echo, `-e` is not required.
    printf 'new\nline'            ### Understood by POSIX printf.
    printf 'new\012line'          ### Valid in POSIX printf.
    printf 'new\x0Aline'       
    printf '%b' 'new\0012line'    ### Valid in POSIX printf.
    

    And therefore, the tool is required to build a string with a new-line:

    $ STR="$(printf 'new\nline')"
    $ printf '%s' "$STR"
    new
    line
    
  3. In some shells, the sequence $' is an special shell expansion. Known to work in ksh93, bash and zsh:

    $ STR=$'new\nline'
    
  4. Of course, more complex solutions are also possible:

    $ echo '6e65770a6c696e650a' | xxd -p -r
    new
    line
    

    Or

    $ echo "new line" | sed 's/ \+/\n/g'
    new
    line
    
2016/03/29

Source: https://stackoverflow.com/questions/3005963
Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Email: [email protected]