回答How to remove the last CR char with cut
时,我发现某些程序确实在字符串的末尾添加了换行符,而其他程序则没有:
假设我们有字符串foobar
并使用printf
进行打印,这样我们就不会得到多余的新行:
$ printf "foobar" | od -c
0000000 f o o b a r
0000006
或使用
echo -n
:$ echo -n "foobar" | od -c
0000000 f o o b a r
0000006
(
echo
的默认行为是返回输出,后跟换行符,因此echo "foobar"
返回f o o b a r \n
)。sed
和cat
都不会添加任何额外的字符:$ printf "foobar" | sed 's/./&/g' | od -c
0000000 f o o b a r
0000006
$ printf "foobar" | cat - | od -c
0000000 f o o b a r
0000006
而
awk
和cut
都可以。 xargs
和paste
还会添加以下结尾的新行:$ printf "foobar" | cut -b1- | od -c
0000000 f o o b a r \n
0000007
$ printf "foobar" | awk '1' | od -c
0000000 f o o b a r \n
0000007
$ printf "foobar" | xargs | od -c
0000000 f o o b a r \n
0000007
$ printf "foobar" | paste | od -c
0000000 f o o b a r \n
0000007
所以我想知道:为什么这种行为不同? POSIX有什么建议吗?
注意,我正在Bash 4.3.11中运行所有这些,其余的是:
最佳答案
某些命令(例如printf
)是libc
库调用(例如printf()
)的简单接口(interface),这些调用不会自动添加\n
。大多数* NIX文本处理命令会在最后一行的末尾添加\n
。
在POSIXv7的Definitions中,文本行的末尾必须带有newline
:
零个或多个非<newline>
字符加上一个终止字符的序列。
如果缺少newline
,它将变为:
文件末尾的一个或多个非<newline>
字符序列。
一般的想法是可以将文本文件视为记录列表,其中每个记录都由\n
终止。换句话说,\n
不是行之间的东西-它是行的一部分。例如,参见 fgets()
函数:\n
始终包含在其中,用于识别是否已完全读取文本行的情况。如果最后一行缺少\n
,则必须做更多检查才能正确读取文件。
通常,只要您的文本文件是由* NIX程序/脚本在* NIX上创建的,就可以期望最后一行已正确终止。但是,许多Java应用程序以及Windows应用程序都无法正确或一致地处理该问题。他们不仅经常忘记添加最后一个\n
,而且经常不正确地将尾随的\n
视为额外的空行。
关于bash - 管道传输到命令: is there any standard?后尾随新行,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36641445/