【发布时间】:2020-06-03 15:03:26
【问题描述】:
echo n | sed '\n\nnd'
使用 GNU sed,上面的命令打印 n。相反,BSD sed 不打印任何内容。
在上下文地址中,构造
\cBREc,其中c是 或 以外的任何字符,应与/BRE/相同。如果c指定的字符出现在 之后,那么它应该被认为是那个文字字符,它不会终止BRE。比如上下文地址\xabc\xdefx,第二个x代表自己,所以BRE就是abcxdef。转义序列
\n应匹配嵌入在模式空间中的。文字 不得用于上下文地址的 BRE 或替代函数中。
但没有详细说明这些陈述引入的矛盾。
我的问题是,哪一个是正确的行为;打印n 还是什么都没有?还是有意留给开发人员选择?
显然 GNU sed 对待 \n 的方式与其他转义序列不同:
$ echo t | sed 'st\ttt' | xxd
00000000: 0a .
$
$ echo n | sed 'sn\nnn' | xxd
00000000: 6e0a n.
【问题讨论】:
-
我的阅读:
\n不是文字换行符(即字符0x0A),因此n应该能够用作上下文地址中的分隔符。这也意味着在这样的地址中的\n是文字 n,而不是换行符。所以我希望它不会打印任何内容。 -
我认为正确的行为是不打印任何内容,因为第二个
\n应该与文字n匹配,因为需要反斜杠以避免n被解释为对应于的结束标记第一个\n。将n作为输出意味着如果您使用\n和n来包含BRE,您将无法匹配任何n。 -
好吧,我不确定是否有权威的答案。 GNU 和 FreeBSD 在那里解释 POSIX 标准的方式显然存在差异——因为我在 Linux 上运行命令后得到
'n'——而其他人则没有。因此,鉴于所有实现都应该使用相同的 POSIX 标准,显然有很多比我更聪明的人在解释上也有困难。这是一个很好的问题,答案可能归结为“它的工作方式就像编码它的人解释每个实现的标准一样”。有人很困惑…… -
有趣的问题!由于在 \nBREn 的情况下不能同时满足这两个规则,并且规范既没有阐明哪个必须优先,也没有调用未定义的行为诅咒,我想说选择(无意)留给实现。对我来说,这两种行为都同样符合这里的标准。确实将
n作为输出意味着无法匹配文字n,但没有任何输出也意味着无法匹配换行符。不确定我更喜欢哪一个。至少 GNU 提供了数字转义序列来匹配任何东西。 -
好吧,当您需要查尔斯或埃德时,他们在哪里?我会这么说,POSIX 标准的这一部分就像 C 标准中的严格别名规则一样写得很好。 (说理性的人可能不同意他们所说的——轻描淡写
:)
标签: sed