在 bash 脚本中使用
printf
,在 "\n"
之后不添加空格不会创建换行符,而添加空格会创建换行符,例如。例:
"\n"
之后没有空格
NewLine=`printf "\n"`
echo -e "Firstline${NewLine}Lastline"
结果:
FirstlineLastline
"\n "
之后有空格
NewLine=`printf "\n "`
echo -e "Firstline${NewLine}Lastline"
结果:
Firstline
Lastline
问题:为什么 1. 没有创建以下结果:
Firstline
Lastline
我知道这个具体问题可以使用其他技术来解决,但我想重点讨论为什么 1. 不起作用。
编辑: 当使用 echo 而不是 printf 时,我得到了预期的结果,但为什么 printf 的工作方式不同?
NewLine=`echo "\n"`
echo -e "Firstline${NewLine}Lastline"
结果:
Firstline
Lastline
反引号运算符删除尾随的新行。参见3.4.5。命令替换位于 http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html
比较:
[alvaro@localhost ~]$ printf "\n"
[alvaro@localhost ~]$ echo "\n"
\n
[alvaro@localhost ~]$ echo -e "\n"
[alvaro@localhost ~]$
echo 命令不会将
\n
视为换行符,除非你告诉他这样做:
NAME
echo - display a line of text
[...]
-e enable interpretation of backslash escapes
POSIX 7 指定了此行为此处:
[...] 使用命令的标准输出,删除替换末尾的一个或多个字符的序列
也许人们会遇到和我一样的问题: 回声 在用背棍包裹的代码内。一个小提示:
printf "astring\n"
# and
printf "%s\n" "astring"
# both have the same effect.
# So... I prefer the less typing one
简短的回答是:
# 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 sent to another place
# before echoing,
buffer="${buffer}\\\\n printf \"$othervar\\\\n\""
一个常见的问题是,如果您在代码中执行以下操作:
echo 'Tomato is nice'
当被反棍包围时会产生错误
command Tomato not found.
解决方法是添加另一个 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
}
现在您可以在提示中调试代码:
(prompt)$ `mySuperFunction "arg1" "etc"`
输出会很好
mydebug: a value
otherdebug: whathever appended using myecho
a third string
并使用
进行内部调试mecho "a string to be hacktyped"
$ printf -v NewLine "\n"
$ echo -e "Firstline${NewLine}Lastline"
Firstline
Lastline
$ echo "Firstline${NewLine}Lastline"
Firstline
Lastline
看起来 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
您编辑的
echo
版本将文字反斜杠-n放入变量$NewLine
中,然后由您的echo -e
解释。如果你这样做:
NewLine=$(echo -e "\n")
echo -e "Firstline${NewLine}Lastline"
您的结果将与情况 #1 相同。要使 that 能够以这种方式工作,您必须转义反斜杠并将整个内容放在单引号中:
NewLine=$(printf '\\n')
echo -e "Firstline${NewLine}Lastline"
或双重转义它:
NewLine=$(printf "\\\n")
当然,你可以直接使用
printf
或者你可以像这样设置你的 NewLine 值:
printf "Firstline\nLastline\n"
或
NewLine=$'\n'
echo "Firstline${NewLine}Lastline" # no need for -e
对于来这里想知道如何在
printf
的参数中使用换行符的人,请使用 %b
而不是 %s
:
$> printf "a%sa" "\n"
a\na
$> printf "a%ba" "\n"
a
a
来自手册:
%b 在相应的参数中展开反斜杠转义序列
我们不需要“echo”或“printf”来创建 NewLine 变量:
NewLine="
"
printf "%q\n" "${NewLine}"
echo "Firstline${NewLine}Lastline"
要保存尾随换行符,请使用
printf
将
printf -v VAR
输出分配给变量
而不是
NewLine=`printf "\n"`
echo -e "Firstline${NewLine}Lastline"
#FirstlineLastline
使用
printf -v NewLine '\n'
echo -e "Firstline${NewLine}Lastline"
#Firstline
#Lastline
根据bash man的说法
3.5.4 命令替换
$(命令)
或
`命令`
Bash 通过执行命令 并将命令替换替换为命令的标准输出,删除所有尾随换行符来执行扩展。嵌入的换行符不会被删除,但在分词过程中可能会被删除。
因此,在添加任何尾随换行符后,bash 将删除它们。
var=$(printf '%s\n%s\n\n\n' 'foo' 'bar')
echo "$var"
输出:
foo
bar
根据
help printf
printf [-v var] format [arguments]
如果提供了 -v 选项,则输出将放入 shell 变量 VAR 的值中,而不是发送到标准输出。
在这种情况下,为了将格式化文本安全复制到变量,请使用
[-v var]
选项:
printf -v var '%s\n%s\n\n\n' 'foo' 'bar'
echo "$var"
输出:
foo
bar
如果添加“则可以正常工作 ”
$ nl=`printf " “` && 回显“1${nl}2” 1 2