BSD sed 与 gsed 中的换行符

BSD sed 与 gsed 中的换行符

FreeBSD 11.2 p7 附带的 sed 提供:

 $ seq 10 | sed 'N; l; D; p'
1$
2$
2$
3$
3$
4$
4$
5$
5$
6$
6$
7$
7$
8$
8$
9$
9$
10$

虽然 gsed (GNU sed 4.7) 给出了相同的脚本:

$ seq 10 | gsed 'N; l; D; p'
1\n2$
2\n3$
3\n4$
4\n5$
5\n6$
6\n7$
7\n8$
8\n9$
9\n10$
10

我们如何解释这种行为差异?

答案1

BSDsed在用于l以视觉上明确的形式输出字符时,不会以视觉上明确的形式输出换行符。

sed(1)在 OpenBSD 上:

 [2addr]l
         (The letter ell.)  Write the pattern space to the standard output
         in a visually unambiguous form.  This form is as follows:

               backslash          \\
               alert              \a
               backspace          \b
               form-feed          \f
               carriage-return    \r
               tab                \t
               vertical tab       \v

(注意没有提及换行符)。

然而, GNUsed在字符集中包含换行符以明确显示。它这样做是作为字符集的扩展,POSIX 标准sed提到(这是 BSD 使用的集合sed)。sed即使--posix在命令行上使用,GNU也会以这种方式运行。

GNUsed也输出10两次,而 BSDsed则不输出。sed使用POSIXLY_CORRECTset 或 with运行 GNU--posix只会使其输出10一次,就像 BSDsed那样。

这是因为 GNUsed默认情况下忽略命令的 POSIX 定义部分sed N

如果没有下一行输入可用,则N命令动词应分支到脚本末尾并退出,而不开始新的循环或将模式空间复制到标准输出。

另请注意,程序p中的sed永远不会执行,因为D会开始新的循环。

相关内容