回答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)。
sedcat都不会添加任何额外的字符:
$ 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

awkcut都可以。 xargspaste还会添加以下结尾的新行:
$ 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中运行所有这些,其余的是:
  • GNU Awk 4.0.1
  • sed(GNU sed)4.2.2
  • cat(GNU coreutils)8.21
  • cut(GNU coreutils)8.21
  • xargs(GNU findutils)4.4.2
  • 粘贴(GNU coreutils)8.21
  • 最佳答案


    某些命令(例如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/

    10-15 08:05