Sed \n\nnd应该做什么?

Sed \n\nnd应该做什么?,sed,Sed,使用GNU时,上述命令打印n。相反,BSD sed不会打印任何内容 说: 在上下文地址中,结构\cBREc,其中c是除或以外的任何字符,应与/BRE/相同。如果c指定的字符出现在a之后,则应将其视为该文字字符,该文字字符不应终止BRE。例如,在上下文地址\xabc\xdefx中,第二个x代表它自己,因此BRE是abcxdef 转义序列\n应与嵌入在图案空间中的a匹配。上下文地址的BRE或替换函数中不得使用文字 但没有详细说明这些陈述所带来的矛盾 我的问题是,哪一个是正确的行为;要打印n还

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

说:

  • 在上下文地址中,结构
    \cBREc
    ,其中
    c
    是除或以外的任何字符,应与
    /BRE/
    相同。如果
    c
    指定的字符出现在a之后,则应将其视为该文字字符,该文字字符不应终止BRE。例如,在上下文地址
    \xabc\xdefx
    中,第二个
    x
    代表它自己,因此BRE是
    abcxdef

  • 转义序列
    \n
    应与嵌入在图案空间中的a匹配。上下文地址的BRE或替换函数中不得使用文字

但没有详细说明这些陈述所带来的矛盾

我的问题是,哪一个是正确的行为;要打印
n
还是什么都不打印?或者,这个选择是故意留给开发者的吗


显然,GNU sed对待
\n
的方式不同于其他转义序列:

echo n | sed '\n\nnd'
根据(以下引用),结论是标准对此不明确,两种行为都是正确的。HP-UX和Solaris采用了与GNU相同的实践,因此它在实现中不是一个bug,但在标准中缺乏明确性

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

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


如果bug跟踪器中出现更新标准以明确说明未指定的建议,我将对此进行编辑以添加链接。

我的阅读:a
\n
不是文字换行符(即字符
0x0A
),因此
n
应该可以用作上下文地址中的分隔符。它还意味着这样一个地址中的
\n
是一个文本n,而不是换行符。因此我希望它不打印任何内容。我认为正确的行为是不打印任何内容,因为第二个
\n
应该与文本
n
匹配,因为需要反斜杠来避免
n
被解释为与第一个
\n
对应的结束标记。将
n
作为输出意味着如果使用
\n
n
来封装BRE,则无法匹配任何
n
。嗯,我不确定是否有足够的权威性来回答。GNU和FreeBSD在解释POSIX标准的方式上有明显的不同——因为我在Linux上运行命令后得到了
'n'
,而其他人则没有。因此,考虑到所有的实现都应该使用相同的POSIX标准,显然有许多比我更聪明的实现在解释上也有困难。这是一个很好的问题,答案可能归结为“它的工作方式与编码它的人解释每个实现的标准的方式相同。”有人感到困惑…有趣的问题!由于这两个规则在\n的情况下不能同时满足,并且规范既没有阐明哪一个必须优先,也没有调用未定义的行为诅咒,因此我认为选择权(无意中)留给了实现。对我来说,这两种行为同样符合这里的标准。事实上,将
n
作为输出意味着无法匹配文字
n
,但没有任何内容作为输出也意味着无法匹配换行符。不知道我喜欢哪一个。至少GNU提供了数字转义序列来匹配任何东西。那么,当你需要它们时,Charles或Ed在哪里?我要说的是,POSIX标准的这一部分编写得很好,就像C标准中的严格别名规则一样。(说理智的人可能不同意他们所说的话,这是一种轻描淡写的说法)
$ echo t | sed 'st\ttt' | xxd
00000000: 0a                                       .
$
$ echo n | sed 'sn\nnn' | xxd
00000000: 6e0a                                     n.