1

Im my debian7.8 bash shell.

str="deb http://ftp.cn.debian.org/debian/ wheezy main contrib non-free  \n  
      deb-src http://ftp.cn.debian.org/debian/ wheezy main contrib non-free  "

echo $str > test  

In my test file it is :

deb http://ftp.cn.debian.org/debian/ wheezy main contrib non-free \n deb-src http://ftp.cn.debian.org/debian/ wheezy main contrib non-free

What i want is the :

deb http://ftp.cn.debian.org/debian/ wheezy main contrib non-free 
deb-src http://ftp.cn.debian.org/debian/ wheezy main contrib non-free

how to express the line feed properly?

showkey
  • 323

3 Answers3

3

Aside from jasonwryan's suggestion, I'd suggest using printf:

$ printf "%s http://ftp.cn.debian.org/debian/ wheezy main contrib non-free\n" deb deb-src > test
$ cat test
deb http://ftp.cn.debian.org/debian/ wheezy main contrib non-free
deb-src http://ftp.cn.debian.org/debian/ wheezy main contrib non-free

Since printf reuses the format string until arguments have been exhausted, it provides a nice way to print repetitive lines.

muru
  • 72,889
2

Just include an actual newline inside the quotes (this works with either single or double quotes). Note that if the second line is indented, the spaces are part of the string. Furthermore always use double quotes around variable substitutions.

str="deb http://ftp.cn.debian.org/debian/ wheezy main contrib non-free
deb-src http://ftp.cn.debian.org/debian/ wheezy main contrib non-free"
echo "$str" > test

Ksh, bash and zsh (but not plain sh) have an alternate quoting syntax $'…' in which backslash begins a C-like escape sequence, so you can write \n to represent a newline. In your case, it would be less readable:

str=$'deb http://ftp.cn.debian.org/debian/ wheezy main contrib non-free\ndeb-src http://ftp.cn.debian.org/debian/ wheezy main contrib non-free'
echo "$str" > test

A here document is often a more readable way to present multiline strings. Note that a here document is passed as standard input to the command¹, not as a command line argument.

cat <<EOF >test
deb http://ftp.cn.debian.org/debian/ wheezy main contrib non-free
deb-src http://ftp.cn.debian.org/debian/ wheezy main contrib non-free
EOF

¹ Or more generally as input if you specify an alternate file descriptor.

0

One option is to use echo -e to expand the escape sequences. The second option is to simply use a "literal" newline (works in bash):

str = "deb ... non-free  "$'\n'"deb-src ... non-free  "
echo "$str"

Note the $'···' notation to insert a literal.

However, having newlines in variables like this is not a good idea. It's harder to read the script, it could lead to silly mistakes and unwanted behaviour if "$str" is given to other programs that either don't understand escape sequences (if \n is used), or uses word splitting ($'' case). Just use an array and iterate over it, it will make it more extensible if you have more lines.

If you just want this in one place in the code, I'd split it into two echo commands, that at least can't go wrong.

Another interesting and probably the best solution if you just want to put it into a file, is a here-document:

cat > test <<EOF
deb http://ftp.cn.debian.org/debian/ wheezy main contrib non-free
deb-src http://ftp.cn.debian.org/debian/ wheezy main contrib non-free
EOF

Further reading: https://stackoverflow.com/questions/9139401/trying-to-embed-newline-in-a-variable-in-bash

orion
  • 12,502