我有一个包含许多错误行的日志文件,例如:
Failed to add email@test.com to database
我可以通过一次grep调用来过滤这些行:
grep -E 'Failed to add (.*) to database'
这样可以正常工作,但我真正想做的是使用grep(或者我将输出传递给其他Unix命令)只输出匹配行的电子邮件地址部分。
这可能吗?
答案 0 :(得分:15)
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并不总是具有完整的正则表达式功能。