我有一个日志文件,其中包含许多错误行,例如:
Failed to add email@test.com to database
我可以用一个 grep 调用过滤这些行:
grep -E 'Failed to add (.*) to database'
这很好用,但我真正想做的是让 grep (或我将输出传递到的另一个 Unix 命令)只输出匹配行的电子邮件地址部分。
这可能吗?
sed
没有 grep 很好:
sed -n 's/Failed to add \(.*\) to database/\1/p' filename
你也可以只管 grep 到自己:)
grep -E 'Failed to add (.*) to database' | grep -Eo "[^ ]+@[^ ]+"
或者,如果“感兴趣的行”是唯一带有电子邮件的行,则只需使用最后一个 grep 命令而不使用第一个命令。
您可以使用 sed:
grep -E 'Failed to add (.*) to database'| sed 's/'Failed to add \(.*\) to database'/\1'
最新版本的 GNU grep 有一个-o
选项可以完全满足您的需求。(-o
用于--only-matching
)。
这应该做的工作:
grep -x -e '(?<=Failed to add ).+?(?= to database)'
它使用肯定的前瞻断言,然后是电子邮件地址的匹配,然后是 postivie 后瞻断言。这确保它匹配整行,但实际上只使用(并因此返回)电子邮件地址部分。
该-x
选项指定 grep 应该匹配行而不是整个文本。
或蟒蛇:
cat file | python -c "import re, sys; print '\r\n'.join(re.findall('add (.*?) to', sys.stdin.read()))"
-r
sed
允许不带反斜杠的正则表达式的选项
sed -n -r 's/Failed to add (.*) to database/\1/p' filename
如果您只想使用 grep 并仅输出匹配的部分行
grep -E -o 'Failed to add (.*) to database'
然后也许如果你想把它写到一个文件中
cat yourlogfile | grep -E -o 'Failed to add (.*) to database' >> outputfile
因此,从 grep 实用程序-o
开始 -o, --only-matching show only nonempty parts of lines that match'
。
如果你想使用grep,使用egrep会更合适;
About egrep
Search a file for a pattern using full regular expressions.
grep 并不总是具有完整的正则表达式功能。