在sed的正则表达式中使用交替“|”


71

我使用的是sed,GNU sed版本4.2.1。 我想使用交替“|”子表达式中的符号。 例如 :

echo "blia blib bou blf" | sed 's/bl\(ia|f\)//g'

应该回来

" blib bou "

但它回来了

"blia blib bou blf".

我怎样才能得到预期的结果?

Answers:


103

“|”还需要一个反斜杠来获得它的特殊含义。

echo "blia blib bou blf" | sed 's/bl\(ia\|f\)//g'

会做你想做的。

如您所知,如果其他所有方法都失败了,请阅读手册:-)。

GNU sed用户手册 , 部分 3.3正则表达式语法概述

`REGEXP1 \ | REGEXP2'

匹配REGEXP1或REGEXP2。

注意反斜杠......

不幸的是,正则表达式的语法并没有真正标准化......有许多变体,其中“特殊字符”需要\而哪些不需要的变体不同。在某些情况下,它甚至可以配置或依赖于交换机(如在GNU中) grep,你可以在三种不同的正则表达方言之间切换)。

这个答案特别适合 GNU sed 。还有其他 sed 变体,例如在BSD中使用的变体,其行为不同。


29
对于其他被这个答案搞糊涂的人仅适用于gnu sed(在os x上使用)而不是香草sed(在os x上使用)。
Andrew Hancox

@AndrewHancox非常感谢你!我准备将所有的头发从头上撕下来(到目前为止,我的发型与头发上的经理相比还不错) - 我知道我知道RegEx足以尝试和\ |但我从未想过OSX实际上可能会使用非gnu sed这一事实。
phatskat

7
标准的BSD / OS X版本 sed 确实支持交替,但只支持“扩展”正则表达式语法( -E ) - 这意味着管道或括号上没有反斜杠: echo "blia blib bou blf" | sed -E 's/bl(ia|f)//g'
Mark Reed

2
我编辑了我的答案,注意它只适用于GNU sed。
sleske

18

由于有关于非Gnu的几条评论 sed 实现:至少在OS X上,您可以使用 -E 论证 sed

将正则表达式解释为扩展(现代)正则表达式而不是基本正则表达式(BRE)。 re_format(7)手册页完全描述了这两种格式。

然后,您可以使用正则表达式元字符而不转义它们。例:

$ echo "blia blib bou blf" | sed -E 's/bl(ia|f)//g'
 blib bou 

10

GNU sed也支持 -r 选项(扩展正则表达式)。这意味着您不必转义元字符:

echo foohello barhello | sed -re "s/(foo|bar)hello/hi/g"

输出:

hi hi

是, -r 选项对于表达式的可读性确实非常有用。那应该是公认的答案。
рüффп

9

\| 也不适用于Solaris 10上的sed。我做的是使用

perl -p -e 's/bl(ia|f)//g'

2
+1是为了便携性,因为如果系统有perl,它将始终使用这种语法,这与sed不同。
evilsoup

4

后续:sed -E允许它在MacOS上。没有反斜杠需要|。

 sed -E 's/this|orthat/oooo/g' infile

1

在Windows上的GnuWin32中,sed的语法是 sed "s/thing1\|thing2/ /g" source > destination

引号必须是类型 " - 对于要解析的命令,这是“必需的”。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.