Adam Asked: 2020-01-31 12:30:44 +0800 CST2020-01-31 12:30:44 +0800 CST 2020-01-31 12:30:44 +0800 CST 为什么 printf 不转义换行符? 772 $ printf "hi" hi$ printf "hi\n" hi $ printf "hi\\n" hi 为什么最后一行不打印hi\n? bash newlines 3 个回答 Voted Best Answer JdeBP 2020-01-31T12:52:03+08:002020-01-31T12:52:03+08:00 这与你所给予的论点无关printf,而与一切有关。printf 在双引号字符串中,shell\\变成\. 因此,您给出的参数printf实际上是hi\n,然后它当然printf会执行自己的转义序列处理。 在双引号字符串中,\shell 完成的转义特别限于影响 ␊、\、`、$和"字符。您会发现它按原样\n传递。printf所以你给出的论点printf实际上hi\n 又是。 小心将转义序列放入printf. 只有一些在Single Unix Specification中有定义的含义。 \n例如,已定义,但\c实际上并未定义。 进一步阅读 https://unix.stackexchange.com/a/359510/5132 POSIX Shell:在双引号内,是否存在 `\` 无法转义 `$`、```、`"`、`\` 或 `<newline>` 的情况? 为什么使用引号时显示单个反斜杠 回显新行和字符串开头 \t 为什么破折号扩展 \\\\ 与 bash 不同? https://unix.stackexchange.com/a/558665/5132 Kusalananda 2020-01-31T12:41:11+08:002020-01-31T12:41:11+08:00 在双引号内,\\n是一个转义(带引号)的反斜杠,后跟一个n. 这被赋予printfas\n并将printf输出一个换行符。 在双引号内(仍然),\n是字符串\n。同样,printf接收一个\n字符串并打印一个换行符。 在双引号内,反斜杠仅在另一个反斜杠、换行符或任何$,`或". “特殊”意味着它删除了下一个字符的特殊含义。如果反斜杠在任何其他字符之前(n例如),那么它只是一个反斜杠字符。 这在POSIX 标准中进行了解释。 \n要以printf格式字符串打印,请使用printf '\\n'or printf "\\\\n",或使用printf '%s' '\n' 通常,printf格式字符串应该是单引号,并且任何变量数据都应该作为附加参数提供,以插入到格式字符串中: printf 'This is how you write a newline: %s\n' '\n' user232326 2020-02-02T09:08:56+08:002020-02-02T09:08:56+08:00 好的,让我们添加另一个观点。 这里有两个层次的解释。一个是shell,另一个是命令(在这种情况下printf)对收到的参数的解释。 在双引号内shell 将不理会大多数序列的反斜杠字符,这是常见的结果: $ printf '%s\n' "\a \b \c \d ... \z \$ \` \\ " \a \b \c \d ... \z $ ` \ 除了, $,`和\which 对 shell 很特别,将它们\删除。 因此,测试您使用的字符串(和其他字符串),我们得到: $ 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
这与你所给予的论点无关
printf
,而与一切有关。printf
在双引号字符串中,shell
\\
变成\
. 因此,您给出的参数printf
实际上是hi\n
,然后它当然printf
会执行自己的转义序列处理。在双引号字符串中,
\
shell 完成的转义特别限于影响 ␊、\
、`
、$
和"
字符。您会发现它按原样\n
传递。printf
所以你给出的论点printf
实际上hi\n
又是。小心将转义序列放入
printf
. 只有一些在Single Unix Specification中有定义的含义。\n
例如,已定义,但\c
实际上并未定义。进一步阅读
在双引号内,
\\n
是一个转义(带引号)的反斜杠,后跟一个n
. 这被赋予printf
as\n
并将printf
输出一个换行符。在双引号内(仍然),
\n
是字符串\n
。同样,printf
接收一个\n
字符串并打印一个换行符。在双引号内,反斜杠仅在另一个反斜杠、换行符或任何
$
,`
或"
. “特殊”意味着它删除了下一个字符的特殊含义。如果反斜杠在任何其他字符之前(n
例如),那么它只是一个反斜杠字符。这在POSIX 标准中进行了解释。
\n
要以printf
格式字符串打印,请使用printf '\\n'
orprintf "\\\\n"
,或使用printf '%s' '\n'
通常,
printf
格式字符串应该是单引号,并且任何变量数据都应该作为附加参数提供,以插入到格式字符串中:好的,让我们添加另一个观点。
这里有两个层次的解释。一个是shell,另一个是命令(在这种情况下
printf
)对收到的参数的解释。在双引号内shell 将不理会大多数序列的反斜杠字符,这是常见的结果:
除了,
$
,`
和\
which 对 shell 很特别,将它们\
删除。因此,测试您使用的字符串(和其他字符串),我们得到:
shell 将对转换
\\
为一个\
。\n
并独自离开\n
。现在,
printf
与第一个参数有特殊关系,它被明确设置为the format
。在格式参数中,一些字符是特殊的(对于 printf),例如:以%
字符开头的有效序列和一些反斜杠字符序列,例如:因此,字符串会
\n
生成一个换行符,但\\n
不会: