【问题标题】:Can you grep a file using a regular expression and only output the matching part of a line?您可以使用正则表达式 grep 文件并仅输出一行的匹配部分吗?
【发布时间】:2010-11-01 18:21:09
【问题描述】:

我有一个包含许多错误行的日志文件,例如:

Failed to add email@test.com to database

我可以通过一次 grep 调用过滤这些行:

grep -E 'Failed to add (.*) to database'

这很好用,但我真正想做的是让 grep(或我将输出传递到的另一个 Unix 命令)只输出匹配行的电子邮件地址部分。

这可能吗?

【问题讨论】:

    标签: unix shell grep


    【解决方案1】:

    sed 不用 grep 也没问题:

    sed -n 's/Failed to add \(.*\) to database/\1/p' filename
    

    【讨论】:

    • 他当然也可以使用 awk !!
    【解决方案2】:

    你也可以只管 grep 到它自己 :)

    grep -E 'Failed to add (.*) to database' | grep -Eo "[^ ]+@[^ ]+"
    

    或者,如果“感兴趣的行”是唯一带有电子邮件的行,则只需使用最后一个 grep 命令而不使用第一个。

    【讨论】:

      【解决方案3】:

      你可以使用 sed:

      grep -E 'Failed to add (.*) to database'| sed 's/'Failed to add \(.*\) to database'/\1'
      

      【讨论】:

      • @rogerdpack:看起来你是对的。 -o 将返回字符串集“无法将 some@addre.ss 添加到数据库”,而 OP 只需要 some@addre.ss。
      • 即使grep -o 有用但不是专门针对正则表达式匹配的组,我的问题是我需要grep 而不是sed 来匹配多行模式下的换行符。我没有找到支持s/.../.../m 的东西,而是使用了grep -z。将其与另一个 grep -oz 配对,并且我的模式合作允许我只选择我想要的部分内容,这些线类型彼此足够不同,我有我的解决方案!考虑到这一点,尤其是在不尝试匹配整行的情况下,这可能是一个补丁区域..
      【解决方案4】:

      最新版本的 GNU grep 有一个 -o 选项,它完全符合您的要求。 (-o 代表--only-matching)。

      【讨论】:

      • 使用-o 将显示与正则表达式匹配的部分,其中包含找到匹配项的整行。但@Olly 只想要第一个子组(电子邮件地址,没有周围的文字)。
      【解决方案5】:

      这应该可以完成工作:

      grep -x -e '(?<=Failed to add ).+?(?= to database)'
      

      它使用肯定的前瞻断言,然后是电子邮件地址的匹配,然后是后向的后瞻断言。这确保它匹配整行,但实际上只消耗(并因此返回)电子邮件地址部分。

      -x 选项指定 grep 应该匹配行而不是整个文本。

      【讨论】:

      • 请注意,您应该为 grep 添加 -P 标志以支持前瞻和后瞻。至少后视表达式应该有固定的长度 - 没有 .* 或其中的任何内容。
      【解决方案6】:

      或蟒蛇:

      cat file | python -c "import re, sys; print '\r\n'.join(re.findall('add (.*?) to', sys.stdin.read()))"
      

      【讨论】:

        【解决方案7】:

        sed 的-r 选项允许不带反斜杠的正则表达式

        sed -n -r 's/Failed to add (.*) to database/\1/p' filename
        

        【讨论】:

          【解决方案8】:

          如果你想使用grep,使用egrep会更合适;

          About egrep
          
          Search a file for a pattern using full regular expressions.
          

          grep 并不总是具有完整的正则表达式功能。

          【讨论】:

          • 他已经使用了 egrep,因为他使用了 -E。与控制输出的问题无关。
          • 你在说什么?如果您看到“标签”,他在询问 UNIX grep,它不是(正如您的回答所建议的)GNU-Everywhere,请参阅 softpanorama.org/Tools/Grep/grep_reference.shtml 以了解 UNIX 上各种 grep 版本的一些评论( NOT GNU GREP),你会看到黑白的,“有限的正则表达式 - grep”,“扩展的正则表达式 - egrep”。所以不管 GNU grep 可能(是)更好的事实,它不会是你可以总是指望的东西,被部署并且可用于你的所有脚本.我的全部观点是你不能指望 grep"basic"
          • 我看不懂重点。除了“Unix”之外,OP对他使用的操作系统只字未提。所以它可以是一个 GNU grep 是默认设置的 Unix(例如 Debian),也可以是一个可以使用一个命令立即安装 GNU grep 的 Unix(带有 pkg​​_add textproc/grep 的 NetBSD)
          猜你喜欢
          • 2017-02-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-18
          • 2020-07-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多