$ printf "hi"
hi$ printf "hi\n"
hi
$ printf "hi\\n"
hi
为什么最后一行不打印hi\n
?
答案1
这与 无关printf
却又与 一切有关你所提出的论点printf
。
在双引号字符串中,shell\\
变为\
.所以你给出的论点printf
实际上是hi\n
,当然然后printf
执行它自己的转义序列处理开启。
在双引号字符串中,\
shell 完成的转义特别限于影响 ␊、\
、`
、$
和"
字符。您会发现它会按原样\n
传递。printf
所以你所提出的论点printf
实际上是hi\n
再次。
将转义序列放入 的格式字符串时要小心printf
。 只有一些中有定义的含义单一 Unix 规范。 例如,\n
已定义,但实际上并未定义。\c
进一步阅读
答案2
在双引号内,\\n
是转义(引号)反斜杠,后跟n
.这被赋予printf
as\n
并将printf
输出换行符。
双引号内(仍然)\n
是字符串\n
。再次printf
接收一个\n
字符串并打印换行符。
双引号内,反斜杠比较特殊仅有的当在另一个反斜杠、换行符或任何$
,`
或之前时"
。 “特殊”意味着它删除了下一个字符的特殊含义。如果反斜杠位于任何其他字符之前(n
例如),那么它只是一个反斜杠字符。
这在中进行了解释POSIX 标准。
要\n
以printf
格式字符串打印,请使用printf '\\n'
或printf "\\\\n"
,或使用printf '%s' '\n'
一般来说,printf
格式字符串应该用单引号引起来,并且任何变量数据都应该作为附加参数给出以插入到格式字符串中:
printf 'This is how you write a newline: %s\n' '\n'
答案3
好吧,让我们添加另一个观点。
这里有两个层次的解释在起作用。一个是 shell,另一个是命令(在本例中printf
)对收到的参数的解释。
双引号内shell 将保留大多数反斜杠字符序列,这是常见的结果:
$ printf '%s\n' "\a \b \c \d ... \z \$ \` \\ "
\a \b \c \d ... \z $ ` \
除了其中$
、`
、 和\
是外壳特有的,请将其\
删除。
因此,测试您使用的字符串(以及其他字符串),我们得到:
$ printf '%s\n' "hi\n" "hi\\n" "hi\\\n" "hi\\\\n" "hi\\\\\n"
hi\n
hi\n
hi\\n
hi\\n
hi\\\n
shell 将成对的转换\\
为一个\
。并独自\n
离开\n
。
现在,printf
与第一个参数有特殊关系,它被明确设置为the format
。在格式参数中,某些字符是特殊的(对于 printf),例如:以字符开头的有效%
序列和一些反斜杠字符序列喜欢:
\\ \a \b \f \n \r \t \v and the special \ddd
因此,字符串\n
会生成换行符,但\\n
不会生成换行符:
$ printf " hi\n hi\\n hi\\\n hi\\\\n"; echo
hi
hi
hi\n hi\n