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

时间:2013-12-27 21:29:57

标签: sed

我发现这是没有意义的事情。

cat config.h的输出:

define somevar foo // Sample variable

这个版本的命令可以将foo更改为bar并保留注释:

sed -e '/somevar/s/foo/bar/' config.h

这不起作用:

sed -e '|somevar|s|foo|bar|' config.h

给出了这个错误:

  

sed:-e expression#1,char 1:unknown命令:`|'

有趣的是,这确实有效:

sed -e '/somevar/s|foo|bar|' config.h

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

错误或功能?

5 个答案:

答案 0 :(得分:31)

这将有效:

sed -e '\|somevar|s|foo|bar|'

GNU sed的man页面非常清楚:

   /regexp/
          Match lines matching the regular expression regexp.

   \cregexpc
          Match lines matching the regular expression regexp.  The  c  may
          be any character.

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

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

  

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

另一方面,在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''.

请注意,该示例使用\xpatternx而不是xpatternx。这就是它给出的所有线索,它没有说明xpatternx不起作用。

根据@that-other-guy的论点,sed(以及perl等{{1}}指出的其他语言)需要这条额外的线索才能正常工作。

答案 1 :(得分:8)

/pattern/允许不同的分隔符会引入解析模糊性。

ispaghetti应该是/spaghett/,还是应该插入像i spaghetti这样的文字?

sy没有这种歧义。当您看到其中任何一个字符时,您知道正在阅读的命令,然后您可以将下一个字符解释为分隔符。

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

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

地址和编辑命令是分开的,因此\$pattern$s_foo_bar_/pattern/s#foo#bar#也可以使用。

答案 2 :(得分:6)

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

sed -e '\|somevar|s|foo|bar|' config.h

或同样容易:

sed -e '\%somevar%s|foo|bar|' config.h

参考:POSIX reference for sed

答案 3 :(得分:3)

我的投票是功能

它们是两个不同的命令,搜索一个/.../和替换一个s/.../.../。据我所知,只允许更改替换命令的分隔符。

中类似。您可以使用/.../进行正则表达式搜索,但如果要更改分隔符,则必须明确将其标记为m的搜索,例如:m|...|

我想这会与一些词法解析问题有关,但我不知道原因。

答案 4 :(得分:2)

特征。在

 sed -e '/somevar/s/foo/bar/' config.h

/somevar/地址。地址必须与其他函数区分开来,例如y(yank),i(插入),a(追加)等等。通常,sed命令被解析为

 [address[,address]]function[arguments]