bash 中的 Printf 示例不会创建换行符

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2676507/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 19:12:32  来源:igfitidea点击:

Printf example in bash does not create a newline

bashprintf

提问by WolfHumble

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

与工作printf在bash脚本,加入无空格后"\n"不创建换行符,而添加的空间中形成一个换行符,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
    
  1. 后面没有空格 "\n"

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

    结果:

    FirstlineLastline
    
  2. 空间后 "\n "

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

    结果:

    Firstline
     Lastline
    

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

问题:为什么不 1. 创建以下结果:

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.

我知道这个特定问题可以使用其他技术解决,但我想集中讨论为什么 1. 不起作用。

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

编辑:当使用 echo 而不是 printf 时,我得到了预期的结果,但为什么 printf 的工作方式不同?

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

Result:

结果:

    Firstline
    Lastline

回答by álvaro González

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

反引号运算符删除尾随的新行。见3.4.5。命令替换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 \nas a newline unless you tell him to do so:

\n除非您告诉他这样做,否则echo 命令不会将其视为换行符:

NAME
       echo - display a line of text
[...]
       -e     enable interpretation of backslash escapes

POSIX 7 specifies this behaviour here:

POSIX 7在此处指定了此行为:

[...] with the standard output of the command, removing sequences of one or more characters at the end of the substitution

[...] 使用命令的标准输出,在替换结束时删除一个或多个字符的序列

回答by Sergio Abreu

Maybe people will come here with the same problem I had: echoing \n inside a code wrapped in backsticks. A little tip:

也许人们会带着我遇到的同样问题来到这里:在用 backsticks 包裹的代码中回显 \n。一个小技巧:

printf "astring\n"
# and 
printf "%s\n" "astring" 
# both have the same effect.
# So... I prefer the less typing one

The short answer is:

简短的回答是:

# Escape \n correctly !

# Using just: printf "$myvar\n" causes this effect inside the backsticks:
printf "banana
"

# So... you must try \n  that will give you the desired 
printf "banana\n"

# Or even \\n if this string is being send to another place 
# before echoing,

buffer="${buffer}\\n printf \"$othervar\\n\""

One common problem is that if you do inside the code:

一个常见的问题是,如果你在代码里面做:

echo 'Tomato is nice'

when surrounded with backsticks will produce the error

当被 backsticks 包围时会产生错误

command Tomato not found.

The workaround is to add another echo -e or printf

解决方法是添加另一个 echo -e 或 printf

printed=0

function mecho(){
  #First time you need an "echo" in order bash relaxes.
  if [[ $printed == 0 ]]; then
    printf "echo -e \\n"
    printed=1
  else
    echo -e "\r\n\r\\n"
  fi
}

Now you can debug your code doing in prompt just:

现在您可以在提示符下调试您的代码:

(prompt)$  `mySuperFunction "arg1" "etc"`

The output will be nicely

输出会很好

 mydebug: a value
 otherdebug: whathever appended using myecho
 a third string

and debuging internally with

并在内部调试

mecho "a string to be hacktyped"

回答by Robert S

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

Firstline
Lastline

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

回答by an0nym0usc0ward

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

看起来 BASH 正在删除尾随的换行符。例如

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

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


 Lastline

回答by Paused until further notice.

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

您编辑的echo版本将文字反斜杠-n 放入变量中$NewLine,然后由您的echo -e. 如果你这样做:

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

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

您的结果将与情况 #1 相同。要使之以这种方式工作,您必须转义反斜杠并将整个内容放在单引号中:

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

or double escape it:

或双重逃脱它:

NewLine=$(printf "\\n")

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

当然,您可以直接使用,也可以printf像这样设置 NewLine 值:

printf "Firstline\nLastline\n"

or

或者

NewLine=$'\n'
echo "Firstline${NewLine}Lastline"    # no need for -e

回答by yabt

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

我们不需要“echo”或“printf”来创建 NewLine 变量:

NewLine="
"
printf "%q\n" "${NewLine}"
echo "Firstline${NewLine}Lastline"

回答by Oleg Razgulyaev

Works ok if you add "\r"

如果您添加“\r”,则可以正常工作

$ nl=`printf "\n\r"` && echo "1${nl}2"
1
2