你能用正则表达式grep一个文件,只输出一行的匹配部分吗?

时间:2009-06-10 10:23:11

标签: unix shell grep

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

Failed to add email@test.com to database

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

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

这样可以正常工作,但我真正想做的是使用grep(或者我将输出传递给其他Unix命令)只输出匹配行的电子邮件地址部分。

这可能吗?

8 个答案:

答案 0 :(得分:15)

没有grep,

sed没问题:

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

答案 1 :(得分:5)

您可以使用sed:

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

答案 2 :(得分:4)

您也可以将grep传递给自己:)

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

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

答案 3 :(得分:3)

GNU grep的最新版本有一个-o选项,它可以完全满足您的需求。 (-o用于--only-matching)。

答案 4 :(得分:2)

这应该做的工作:

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

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

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

答案 5 :(得分:1)

或python:

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

答案 6 :(得分:-1)

-r

sed选项允许没有反斜杠的正则表达式

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

答案 7 :(得分:-2)

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

About egrep

Search a file for a pattern using full regular expressions.

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