[英]Printf example in bash does not create a newline
Working with printf
in a bash script, adding no spaces after "\n"
does not create a newline, whereas adding a space creates a newline, eg:在 bash 脚本中使用printf
,在"\n"
之后不添加空格不会创建换行符,而添加空格会创建换行符,例如:
No space after "\n"
"\n"
后面没有空格
NewLine=`printf "\n"` echo -e "Firstline${NewLine}Lastline"
Result:结果:
FirstlineLastline
Space after "\n "
"\n "
后的空格
NewLine=`printf "\n "` echo -e "Firstline${NewLine}Lastline"
Result:结果:
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
The backtick operator removes trailing new lines.反引号运算符删除尾随的新行。 See 3.4.5.见3.4.5。 Command substitution at http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html命令替换在http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html
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: echo 命令不会将\\n
视为换行符,除非您告诉他这样做:
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 [...] 使用命令的标准输出,在替换结束时删除一个或多个字符的序列
Maybe people will come here with the same problem I had: echoing \\n inside a code wrapped in backsticks.也许人们会带着我遇到的同样问题来到这里:在用 backsticks 包裹的代码中回显 \\n。 A little tip:一个小技巧:
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 $1\\\\n"
printed=1
else
echo -e "\r\n\r$1\\\\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"
$ printf -v NewLine "\n"
$ echo -e "Firstline${NewLine}Lastline"
Firstline
Lastline
$ echo "Firstline${NewLine}Lastline"
Firstline
Lastline
It looks like BASH is removing trailing newlines.看起来 BASH 正在删除尾随的换行符。 eg例如
NewLine=`printf " \n\n\n"`
echo -e "Firstline${NewLine}Lastline"
Firstline Lastline
NewLine=`printf " \n\n\n "`
echo -e "Firstline${NewLine}Lastline"
Firstline
Lastline
Your edited echo
version is putting a literal backslash-n into the variable $NewLine
which then gets interpreted by your echo -e
.您编辑的echo
版本将文字反斜杠-n 放入变量$NewLine
,然后由您的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.您的结果将与情况 #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
或者你可以像这样设置你的 NewLine 值:
printf "Firstline\nLastline\n"
or或者
NewLine=$'\n'
echo "Firstline${NewLine}Lastline" # no need for -e
For people coming here wondering how to use newlines in arguments to printf
, use %b
instead of %s
:对于来这里想知道如何在printf
参数中使用换行符的人,请使用%b
而不是%s
:
$> printf "a%sa" "\n"
a\na
$> printf "a%ba" "\n"
a
a
From the manual:从手册:
%b expand backslash escape sequences in the corresponding argument %b 在相应的参数中展开反斜杠转义序列
We do not need "echo" or "printf" for creating the NewLine variable:我们不需要“echo”或“printf”来创建 NewLine 变量:
NewLine="
"
printf "%q\n" "${NewLine}"
echo "Firstline${NewLine}Lastline"
To save trailing newlines, assign printf
output to the variable with printf -v VAR
要保存尾随换行符,请使用printf -v VAR
将printf
output 分配给变量
instead of代替
NewLine=`printf "\n"`
echo -e "Firstline${NewLine}Lastline"
#FirstlineLastline
use利用
printf -v NewLine '\n'
echo -e "Firstline${NewLine}Lastline"
#Firstline
#Lastline
According to bash man根据 bash 人
3.5.4 Command Substitution 3.5.4 命令替换
$(command) $(命令)
or或者
`command` `命令`
Bash performs the expansion by executing command and replacing the command substitution with the standard output of the command, with any trailing newlines deleted . Bash通过执行命令并用命令的标准 output 替换命令替换来执行扩展,删除任何尾随换行符。 Embedded newlines are not deleted, but they may be removed during word splitting.嵌入的换行符不会被删除,但它们可能会在分词过程中被删除。
So, after adding any trailing newlines, bash will delete them.因此,在添加任何尾随换行符后,bash 将删除它们。
var=$(printf '%s\n%s\n\n\n' 'foo' 'bar')
echo "$var"
output: output:
foo
bar
According to help printf
根据help printf
printf [-v var] format [arguments]
If the -v option is supplied, the output is placed into the value of the shell variable VAR rather than being sent to the standard output.如果提供了 -v 选项,则 output 被放入 shell 变量 VAR 的值中,而不是发送到标准 output。
In this case, for safe copying of formatted text to the variable, use the [-v var]
option:在这种情况下,为了将格式化文本安全复制到变量,请使用[-v var]
选项:
printf -v var '%s\n%s\n\n\n' 'foo' 'bar'
echo "$var"
output: output:
foo
bar
Works ok if you add "\\r"如果您添加“\\r”,则可以正常工作
$ nl=`printf "\n\r"` && echo "1${nl}2" 1 2
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.