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_CORRECT
set 或 with运行 GNU--posix
只会使其输出10
一次,就像 BSDsed
那样。
这是因为 GNUsed
默认情况下忽略命令的 POSIX 定义部分sed
N
:
如果没有下一行输入可用,则
N
命令动词应分支到脚本末尾并退出,而不开始新的循环或将模式空间复制到标准输出。
另请注意,程序p
中的sed
永远不会执行,因为D
会开始新的循环。