回答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中运行所有这些,其余的是:
答案 0 :(得分:1)
所以我想知道:为什么这种行为不同? POSIX对此有什么建议吗?
某些命令(例如printf
)是libc
库调用的简单接口(例如printf()
),它们不会自动添加\n
。大多数* NIX文本处理命令会在最后一行的末尾添加\n
。
从POSIXv7的Definitions开始,文字行最后必须有newline
:
3.206行
零个或多个非
<newline>
个字符加上终止字符的序列。
如果缺少newline
,则会变为:
3.195不完整的行
文件末尾的一个或多个非
<newline>
字符的序列。
一般的想法是文本文件可以被视为记录列表,其中每个记录都由\n
终止。换句话说,\n
不是行之间的东西 - 它是行的一部分。例如,请参阅fgets()
函数:始终包含\n
,用于标识文本行是否已完全读取的情况。如果最后一行缺少\n
,则必须进行更多检查才能正确读取文件。
通常,只要您的文本文件是在* NIX * NIX程序/脚本上创建的,就可以期望最后一行正确终止。但是许多Java应用程序以及Windows应用程序都无法正确或一致地处理这些问题。他们不仅经常忘记添加最后一个\n
,通常他们也会错误地将尾随\n
视为额外的空行。