【问题标题】:What's the difference between "grep -e" and "grep -E" [closed]“grep -e”和“grep -E”有什么区别[关闭]
【发布时间】:2013-06-12 09:22:13
【问题描述】:

我有一个文件test.txt,其中有一些格式化的电话号码。我正在尝试使用grep 来查找包含电话号码的行。

grep -e "[0-9]{3}-[0-9]{3}-[0-9]{4}" test.txt 似乎不起作用并且没有给出任何结果。但是grep -E "[0-9]{3}-[0-9]{3}-[0-9]{4}" test.txtworks。所以我想知道这两个选项有什么区别。

根据man grep

-E, --extended-regexp 将模式解释为扩展的正则表达式(即强制 grep 表现得像 egrep)。

-e 模式,--regexp=模式 指定在搜索输入期间使用的模式:输入 如果它与任何指定的模式匹配,则选择该行。 此选项在使用多个 -e 选项时最有用 指定多个模式,或者当一个模式以破折号开头时 (`-')。

但我不太明白。什么是扩展正则表达式?

【问题讨论】:

  • 查看 unix.stackexchange 以了解这些类型的问题。这实际上是以下内容的副本:unix.stackexchange.com/questions/50512/…
  • @jwd: 或堆栈溢出;或 Apple,或 Ubuntu,或......这里的主题非常适合。
  • 好吧,我认为@JonathanLeffler 实际上并不是真的在 Apple 或 Ubuntu 上。它的措辞与此处相关,因为给出了一个具体的示例,将其框架为一个“编程”问题,而不是一个纯粹的技术 UNIX 问题。当然,@user2440712(我希望他们会想到真正的用户名)运行的系统也会在一定程度上影响答案,因为不同版本的grep 比比皆是。

标签: linux shell grep


【解决方案1】:

正如您所提到的,grep -E 用于扩展正则表达式-e 用于基本正则表达式。从手册页:

编辑:正如 Jonathan 在下面指出的,grep -e“指定以下参数是要匹配的正则表达式之一。”

基本与扩展正则表达式

在基本正则表达式中,元字符 ?+{|() 丢失 它们的特殊含义;而是使用反斜杠版本\?\+\{\|\(\)

传统的egrep 不支持{ 元字符,还有一些egrep 实现支持\{,因此可移植脚本应避免{ grep -E 模式并且应该使用 [{] 来匹配文字 {

GNU grep -E 试图通过假设 { 来支持传统用法 如果它将是无效间隔规范的开始,则不是特别的。 例如,命令 grep -E '{1' 搜索两个字符 string {1 而不是在正则表达式中报告语法错误。 POSIX.2 允许将此行为作为扩展,但可移植脚本应该 避免它。

但手册页非常简洁,因此有关详细信息,请查看此链接:

http://www.regular-expressions.info/posix.html

手册中关于{ 元字符的部分虽然专门讨论了您所看到的差异。

grep -e "[0-9]{3}-[0-9]{3}-[0-9]{4}" 

不起作用,因为它没有像您期望的那样处理 { 字符。而

grep -E "[0-9]{3}-[0-9]{3}-[0-9]{4}" 

因为那是扩展的 grep 版本——或者例如 egrep 版本。

【讨论】:

  • -E 用于扩展正则表达式,之前由egrep 提供,但-e 不适用于基本正则表达式;它只是指定以下参数是要匹配的正则表达式之一。
  • 啊,花了一天的时间才终于克服了评论声誉障碍,感谢您的支持 :) 是的 - 正如 Jonathan Leffler 所说。我正在相应地更新答案......谢谢!
  • 嘿乔纳森,不确定你是否在看,但由于我对 SO 很陌生,我只是想确保我在修订方面遵循了正确的协议,我注意到你做了一些.我需要做任何事情来接受它们还是自动应用它们(啊 - 看起来它们是自动应用的 - 没关系那个 Q.)?无论如何,感谢您的编辑!对于阅读的人,请查看乔纳森的答案。
  • 具有足够声誉的人(2000 或更多;一般参见FAQ 和具体的Privileges/Edit)无需经过正式审核流程即可编辑问题和答案。权限较低的人可以编辑问题或答案,但它需要经过审核过程,并且必须有 3 人批准。如果您不同意我所做的任何更改,或者想详细说明您的答案,您可以随时进行另一次编辑,以便您的 ID 出现在已编辑的列中。但是您无需做任何事情。如果您不同意,您可以回滚更改。
  • 我明白了,谢谢 - 这听起来完全合理。至于这些编辑,我觉得它们非常好,再次感谢乔纳森!
【解决方案2】:

这是一个简单的测试:

$ cat file
apple is a fruit
so is orange
but onion is not

$ grep -e 'but' -e 'fruit' file #Allows you to pass multiple patterns explicitly
apple is a fruit
but onion is not

$ grep -E 'is (a|not)' file #Allows you to use extended regular expressions like ?, +, | etc
apple is a fruit
but onion is not

【讨论】:

    【解决方案3】:

    grep-e 选项只是表示以下参数是正则表达式。因此:

    grep -e 'some.*thing' -r -l .
    

    在当前目录及其所有子目录中的所有文件的一行中查找some,后跟thing。也可以通过以下方式实现:

    grep -r -l 'some.*thing' .
    

    (在 Linux 上,GNU getopt() 的行为混淆了这种情况,除非您在环境中设置 POSIXLY_CORRECT,否则会置换选项,因此您也可以运行:

    grep 'some.*thing' -r -l .
    

    并得到相同的结果。在 POSIX 和其他不使用 GNU getopt() 的系统下,选项需要在参数之前,grep 会查找一个名为 -r 的文件和另一个名为 -l 的文件。)

    -E 选项将正则表达式从'basic' to 'extended' 更改。可以和-e一起使用:

    grep    -e "[0-9]{3}-[0-9]{3}-[0-9]{4}" test.txt
    grep -E -e "[0-9]{3}-[0-9]{3}-[0-9]{4}" test.txt
    

    ERE 选项表示的正则表达式或多或少与 egrep 命令识别的相同,它不再是 POSIX 的一部分(已被 grep -Efgrep 替换为grep -F)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-24
      相关资源
      最近更新 更多