为什么备用分隔符不适用于sed -e'/ pattern/s/a/b /'?

cod*_*mas 20 sed

这是我发现的没有意义的东西.

产量cat config.h:

define somevar foo // Sample variable
Run Code Online (Sandbox Code Playgroud)

此版本的命令用于将foo更改为bar并保留注释:

sed -e '/somevar/s/foo/bar/' config.h
Run Code Online (Sandbox Code Playgroud)

这不起作用:

sed -e '|somevar|s|foo|bar|' config.h
Run Code Online (Sandbox Code Playgroud)

给出了这个错误:

sed:-e表达式#1,char 1:未知命令:`|'

有趣的是,这确实有效:

sed -e '/somevar/s|foo|bar|' config.h
Run Code Online (Sandbox Code Playgroud)

也许我错过了文档的某些部分.在同一个sed命令中有两个不同的分隔符似乎很奇怪.

错误或功能?

Sto*_*ica 31

这将有效:

sed -e '\|somevar|s|foo|bar|'
Run Code Online (Sandbox Code Playgroud)

manGNU sed 的页面非常清楚:

   /regexp/
          Match lines matching the regular expression regexp.

   \cregexpc
          Match lines matching the regular expression regexp.  The  c  may
          be any character.
Run Code Online (Sandbox Code Playgroud)

也就是说,c可能是任何字符,但起始\是强制性的.

我没有FreeBSD,但根据@bonsaivikingman页面,也很清楚:

开口分隔符需要以反斜杠开头,除非它是斜杠.

另一方面,在OSX中,这一点根本不清楚:

      In a context address, any character other than a backslash (``\'')
      or newline character may be used to delimit the regular expression.
      Also, putting a backslash character before the delimiting character
      causes the character to be treated literally.  For example, in the
      context address \xabc\xdefx, the RE delimiter is an ``x'' and the
      second ``x'' stands for itself, so that the regular expression is
      ``abcxdef''.
Run Code Online (Sandbox Code Playgroud)

请注意,那里使用的示例\xpatternx而不仅仅是xpatternx.这就是它给出的所有线索,它并没有说清楚它xpatternx不会起作用.

基于对论点@那-其他-盖伊,这是有道理的,sed(等其他语言perl@Birei指出)需要这个额外的线索才能正常工作.

  • 它位于[GNU sed的手册页](http://linux.die.net/man/1/sed)中,FreeBSD的手册页更加清晰:"开头分隔符需要以反斜杠开头,除非它是斜杠. " (3认同)

tha*_*guy 8

允许不同的分隔符/pattern/会引入解析歧义.

ispaghetti认为是像/spaghett/呢,还是应该像插入文本i spaghetti

随着s而且y没有这种模糊性.当您看到其中任何一个字符时,您知道正在阅读的命令,然后您可以将下一个字符解释为分隔符.

我们可以解决这种歧义,/pattern/如果我们用类似的可识别字符开始它,并且sed确实有一个单独的地址说明符:反斜杠,如\|pattern|(这与转义不同).

因此我们可以写\|pattern|s|foo|bar|.

地址和编辑命令是独立的,所以\$pattern$s_foo_bar_/pattern/s#foo#bar#正常工作.

  • 很好地讨论了解析歧义,但是如果第一个分隔符前面有反斜杠"\",则sed*会提供此功能. (2认同)

bon*_*ing 6

您绝对可以使用备用分隔符作为匹配的地址(/regex/),但您需要告诉sed您打算与该分隔符进行匹配.你这样做的方法是使用前导反斜杠\.所以你的命令可以是:

sed -e '\|somevar|s|foo|bar|' config.h
Run Code Online (Sandbox Code Playgroud)

或者同样容易:

sed -e '\%somevar%s|foo|bar|' config.h
Run Code Online (Sandbox Code Playgroud)

参考:POSIX参考sed