如何在Cygwin中使用grep命令的正则表达式OR操作符?

53

我需要从一个单一的文件中返回两个不同匹配的结果。

grep "string1" my.file

正确地返回了my.file中string1的唯一实例。

grep "string2" my.file

正确地返回了在my.file中string2的唯一实例

但是

grep "string1|string2" my.file

没有返回任何内容

在正则表达式测试应用程序中,该语法是正确的,那么为什么在Cygwin的grep中它不起作用呢?

5个回答

77

如果在基本正则表达式中使用未转义的|字符,只会匹配该字符本身。例如,如果你有一个文件内容为

string1
string2
string1|string2

使用命令 grep "string1|string2" my.file 只会匹配最后一行

$ grep "string1|string2" my.file
string1|string2
为了使用替换运算符|,你可以:
  1. 使用基本正则表达式(只用grep)并在正则表达式中转义|字符

    grep "string1\|string2" my.file

  2. 使用扩展正则表达式与egrepgrep -E,如朱利安在他的回答中指出的那样

    grep -E "string1|string2" my.file

  3. 如果你想匹配两个不同的模式,也可以在-e选项中分别指定它们:

    grep -e "string1" -e "string2" my.file

你可能会发现grep参考资料的以下章节有用:

那个代码是可以运行的,但我本来期望这个序列会转义管道符号的功能,所以正则表达式会寻找 "string1|string2" 而不是在它们之间进行或操作。 - rob
6
正如@Julian已经指出的那样,如果你在使用元字符如|+?()时希望它们正常工作而无需转义(就像普通的正则表达式一样),你应该使用egrep。例如,egrep "string1|string2"可以实现或的效果。如果你转义了|元字符,仍然可以使用grep - Xavi López
1
对于-E要小心:OP说的是_cygwin_,这意味着正在使用GNU grep。这个grep默认使用扩展正则表达式;如果你想要基本正则表达式,必须明确请求(选项-G)。 - undefined

10

您可能需要使用egrepgrep -E命令。管道OR符号是'扩展' grep 的一部分,可能不受基本Cygwin grep的支持。

此外,您可能需要转义管道符号。


我将查询更改为 grep -E "string1|string2" my.file 这样可以正确匹配两个结果 使用-E转义管道符导致没有结果 - rob
2
grep -E 相当于 egrep;使用 egrep 可能更符合惯用语。在 grep 中,| 只是普通字符,而 \| 指定了替换。在 egrep 中,| 指定了替换,而 \| 只是垂直条形字符。 - Keith Thompson

6

我发现最好、最清晰的方法是:

grep -e REG1 -e REG2 -e REG3 _FILETOGREP_

我从不使用管道,因为它不够明显,而且很难工作。


0

您可以通过阅读精细的手册grep(1)来获取此信息,您可以通过运行'man grep'找到它。它描述了grep和egrep、基本和正则表达式之间的区别,以及关于grep的许多其他有用信息。


3
我不确定你是想帮助原帖作者还是贬低他。如果你的愿望是帮助,提供一个相关链接和手册中的引用会更有帮助。 - Eric Wilson
我的意图是通过教他一个终身技能来帮助OP:阅读手册。很明显他没有这样做。我已经编辑了帖子,引用了grep(1)来提醒他。 - Andrew Schulman
5
我会根据你的编辑,取消我之前的投反对票。我相当确定这种生活技能最好通过解释和示例来学习,而不是单纯地劝告。 - Eric Wilson

0

grep -P

虽然有点晚了,但其他答案对我都没有用。(我在搜索\d数字。)这个方法有效:

grep -P "string1|string2" my.file

From grep --help:

  -P, --perl-regexp         PATTERNS are Perl regular expressions

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接