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

Unix 是否可以使用正则表达式对文件进行grep处理,并仅输出行的匹配部分?,unix,shell,grep,Unix,Shell,Grep,我有一个日志文件,其中包含许多错误行,例如: Failed to add email@test.com to database 我可以通过一次grep呼叫过滤这些线路: grep -E 'Failed to add (.*) to database' 这很好,但我真正想做的是让grep(或我将输出传递到的另一个Unix命令)只输出匹配行的电子邮件地址部分 这可能吗?您可以使用sed: grep -E 'Failed to add (.*) to database'| sed 's/'Fail

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

Failed to add email@test.com to database
我可以通过一次grep呼叫过滤这些线路:

grep -E 'Failed to add (.*) to database'
这很好,但我真正想做的是让grep(或我将输出传递到的另一个Unix命令)只输出匹配行的电子邮件地址部分

这可能吗?

您可以使用sed:

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

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

sed
没有grep也可以:

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

这应该可以做到:

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

grep-x-e'(?如果你想使用grep,使用egrep会更合适

About egrep

Search a file for a pattern using full regular expressions.

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

最近版本的GNU grep有一个
-o
选项,它可以完全满足您的需要。(
-o
用于
——仅匹配
)。

您也可以将grep传输到自身:)


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

-r
sed的选项允许regexp没有反斜杠

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

当然他也可以用awk!!他已经使用了egrep,因为他使用了-E。与控制输出的问题无关。你在说什么?如果你看到“标签”,他是在问关于UNIX grep的问题,它不是(正如你的答案所暗示的)到处都是GNU,请参阅一些关于UNIX上各种grep版本(不是GNU grep)的评论,你会看到黑白的,“Limited regex-grep”,“Extended regex-egrep”。因此,不管GNUGREP可能更好,它都不是你可以一直依靠的东西,它被部署并可用于所有脚本。我的全部观点是,你不能指望grep“basic”,我看不到这一点。OP除了“Unix”之外没有提到他使用的操作系统。因此,它可以是一个默认使用GNU grep的Unix(例如Debian),也可以是一个使用
-o
显示与regex匹配的部分而不是找到匹配的整行的命令(带有pkg_add textproc/grep的NetBSD)立即安装GNU grep的Unix。但是@Olly只想要第一个子组(电子邮件地址,没有周围的文本)。@rogerdpack:看起来你是对的<代码>-o
将返回字符串集“添加失败”some@addre.ss,而OP只需要some@addre.ss.My即使
grep-o
非常有用,但并不特别适用于正则表达式匹配组,问题是我需要
grep
over
sed
在多行模式下匹配换行符。我没有找到支持
s/../…/m
的东西,而是使用
grep-z
。再加上另一个
grep-oz
和我的模式合作,让我只选择我想要的内容的一部分,这些行类型彼此之间差异很大,我有了我的解决方案!考虑到这一点,特别是在不尝试匹配整行的情况下,这可能是一个补丁区域。注意,您应该为grep添加
-P
标志,以支持向前看和向后看。并且至少look-behind表达式应该有固定的长度-没有
*
或任何内容。
sed -n -r 's/Failed to add (.*) to database/\1/p' filename