tags:

views:

402

answers:

6

Working with printf in a bash script, adding no spaces after "\n" does not create a newline, whereas adding a space creates a newline, e. g.:

  1. No space after "\n"

    NewLine=`printf "\n"`
    echo -e "Firstline${NewLine}Lastline"
    

    Result:

    FirstlineLastline
    
  2. Space after "\n "

    NewLine=`printf "\n "`
    echo -e "Firstline${NewLine}Lastline"
    

    Result:

    Firstline
     Lastline
    

Question: Why doesn't 1. create the following result:

Firstline 
Lastline

I know that this specific issue could have been worked around using other techniques, but I want to focus on why 1. does not work.

Edited: When using echo instead of printf, I get the expected result, but why does printf work differently?

    NewLine=`echo "\n"`
    echo -e "Firstline${NewLine}Lastline"

Result:

    Firstline
    Lastline
+1  A: 

It looks like BASH is removing trailing newlines. e.g.

NewLine=`printf " \n\n\n"`
echo -e "Firstline${NewLine}Lastline"
Firstline Lastline

NewLine=`printf " \n\n\n "`
echo -e "Firstline${NewLine}Lastline"
Firstline


 Lastline
an0nym0usc0ward
A: 
oraz
The Windows line feed is \r\n, it you were referring to that :-?
Álvaro G. Vicario
@Alvaro: just hack
oraz
+4  A: 

The backtick operator removes trailing new lines. See 3.4.5. Command substitution at http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html

Note on edited question

Compare:

[alvaro@localhost ~]$ printf "\n"

[alvaro@localhost ~]$ echo "\n"
\n
[alvaro@localhost ~]$ echo -e "\n"


[alvaro@localhost ~]$

The echo command doesn't treat \n as a newline unless you tell him to do so:

NAME
       echo - display a line of text
[...]
       -e     enable interpretation of backslash escapes
Álvaro G. Vicario
The thing is that this does not seem to be the case for the example in the edited part of the post, i.e the part: NewLine=`echo "\n"`
WolfHumble
So I guess the **conclusion** is that:**1)** Printf works differently than echo in this case, in that echo requires "-e" for creating the actual newline**2)** All trailing newlines gets deleted, both in printf and in echo -e, as described in: http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html The post by mr. Dennis Williamson below was also useful to point out these issues. Thx!
WolfHumble
+1  A: 

Your edited echo version is putting a literal backslash-n into the variable $NewLine which then gets interpreted by your echo -e. If you did this instead:

NewLine=$(echo -e "\n")
echo -e "Firstline${NewLine}Lastline"

your result would be the same as in case #1. To make that one work that way, you'd have to escape the backslash and put the whole thing in single quotes:

NewLine=$(printf '\\n')
echo -e "Firstline${NewLine}Lastline"

or double escape it:

NewLine=$(printf "\\\n")

Of course, you could just use printf directly or you can set your NewLine value like this:

printf "Firstline\nLastline\n"

or

NewLine=$'\n'
echo "Firstline${NewLine}Lastline"    # no need for -e
Dennis Williamson
this is confusing and -- if one where to nitpick -- also wrong. for example: in the second code block you say you escape the newline but you really only escape the backslash (the "escape").
hop
Sorry for the confusion. I'll try to clarify it.
Dennis Williamson
Thx. for this answer as well. Was not able to upvote it because "it was to old to be changed", according to the system.
WolfHumble
+1  A: 

We do not need "echo" or "printf" for creating the NewLine variable:

NewLine="
"
printf "%q\n" "${NewLine}"
echo "Firstline${NewLine}Lastline"
yabt
A: 
$ printf -v NewLine "\n"
$ echo -e "Firstline${NewLine}Lastline"

Firstline
Lastline

$ echo "Firstline${NewLine}Lastline"
Firstline
Lastline
Robert S