代码之家  ›  专栏  ›  技术社区  ›  Olly

是否可以使用正则表达式对文件进行grep处理,并仅输出行的匹配部分?

  •  11
  • Olly  · 技术社区  · 17 年前

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

    Failed to add email@test.com to database
    

    我可以通过一次grep呼叫过滤这些线路:

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

    这可能吗?

    8 回复  |  直到 17 年前
        1
  •  14
  •   Maciej Łebkowski    17 年前

    sed 没有grep也可以:

    sed -n 's/Failed to add \(.*\) to database/\1/p' filename
    
        2
  •  7
  •   Valentin    13 年前

    您也可以通过管道将grep传输到自身:)

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

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

        3
  •  5
  •   Nathan Fellman    17 年前

    您可以使用sed:

    grep -E 'Failed to add (.*) to database'| sed 's/'Failed to add \(.*\) to database'/\1'
    
        4
  •  5
  •   bortzmeyer    17 年前

    -o 选项,它完全符合您的要求。( 是为了 --only-matching ).

        5
  •  2
  •   Noldorin    17 年前

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

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

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

        6
  •  1
  •   SpliFF    17 年前

    或python:

    cat file | python -c "import re, sys; print '\r\n'.join(re.findall('add (.*?) to', sys.stdin.read()))"
    
        7
  •  1
  •   Mikhail V.    11 年前

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

    sed -n -r 's/Failed to add (.*) to database/\1/p' filename
    
        8
  •  -2
  •   RandomNickName42    17 年前

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

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

    grep并不总是具有regex的完整功能。