【问题标题】:What is \n\nnd supposed to do?\n\nnd 应该做什么?
【发布时间】:2020-06-03 15:03:26
【问题描述】:
echo n | sed '\n\nnd'

使用 GNU sed,上面的命令打印 n。相反,BSD sed 不打印任何内容。

POSIX sed spec. 说:

  • 在上下文地址中,构造\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


【解决方案1】:

根据Geoff Clare's response(引用如下)得出的结论是标准对此并不清楚,两种行为都是正确的。 HP-UX 和 Solaris 采用了与 GNU 相同的做法,因此这不是实现中的错误,而是标准缺乏明确性。

两者都不比另一个更正确,因为正如您自己所说,标准不清楚。正式的解释会说“标准在这个问题上不清楚,并且基于此的替代实现之间没有一致性区别。”

鉴于实现不同,我们可能应该明确地未指定行为。

如果更新标准以明确声明未指定的提案出现在错误跟踪器中,我将对其进行编辑以添加指向该链接的链接。

【讨论】:

    猜你喜欢
    • 2011-02-23
    • 1970-01-01
    • 2015-09-17
    • 1970-01-01
    • 2016-04-10
    • 2014-10-26
    • 2011-06-20
    • 2012-11-24
    • 1970-01-01
    相关资源
    最近更新 更多