在管道输入命令后跟踪新行:是否有任何标准?

时间:2016-04-15 07:59:08

标签: bash unix posix gnu

回答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
  • paste(GNU coreutils)8.21

1 个答案:

答案 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视为额外的空行。

相关问题