这是我发现的没有意义的东西.
产量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,但根据@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''.
Run Code Online (Sandbox Code Playgroud)
请注意,那里使用的示例\xpatternx而不仅仅是xpatternx.这就是它给出的所有线索,它并没有说清楚它xpatternx不会起作用.
基于对论点@那-其他-盖伊,这是有道理的,sed(等其他语言perl如@Birei指出)需要这个额外的线索才能正常工作.
允许不同的分隔符/pattern/会引入解析歧义.
被ispaghetti认为是像/spaghett/呢,还是应该像插入文本i spaghetti?
随着s而且y没有这种模糊性.当您看到其中任何一个字符时,您知道正在阅读的命令,然后您可以将下一个字符解释为分隔符.
我们可以解决这种歧义,/pattern/如果我们用类似的可识别字符开始它,并且sed确实有一个单独的地址说明符:反斜杠,如\|pattern|(这与转义不同).
因此我们可以写\|pattern|s|foo|bar|.
地址和编辑命令是独立的,所以\$pattern$s_foo_bar_和/pattern/s#foo#bar#正常工作.
您绝对可以使用备用分隔符作为匹配的地址(/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