BSD sed 与 gsed 中的换行符

viu*_*ser 7 bsd sed gnu newlines

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$
Run Code Online (Sandbox Code Playgroud)

虽然 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
Run Code Online (Sandbox Code Playgroud)

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

Kus*_*nda 8

BSD sed,使用时l在视觉上明确的形式输出字符,不输出换行符在视觉上明确的形式。

来自OpenBSD 上的sed(1)

 [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
Run Code Online (Sandbox Code Playgroud)

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

sed但是,GNU在字符集中包含换行符以明确显示。它这样做是作为POSIX 标准sed提及的字符集(这是 BSDsed使用的集)的扩展。sed即使--posix在命令行上使用GNU也是如此。

GNUsed也输出10两次,而 BSDsed没有。sed使用POSIXLY_CORRECTset 或 with运行 GNU--posix10只输出一次,就像 BSDsed那样。

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

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

还要注意的是,p在你的sed程序不会被执行,因为D开始一个新的循环。

  • 另一个区别是使用 BSD sed 显示一次 10,这次 GNU sed 的行为类似于使用 POSIXLY_CORRECT 的 BSD sed。这就是为什么在未启用 `-n` 时你通常想要使用 `$!N` 而不是 `N` 的原因。 (2认同)