grep表示“期限”,但排除“另一个期限”


28

我正在尝试建立一个grep搜索来搜索一个词,但排除具有第二个词的行。我想使用多个-e "pattern"选项,但是没有用。

这是我尝试的命令及其生成的错误消息的示例。

grep -i -E "search term" -ev "exclude term"
grep: exclude term: No such file or directory

在我看来,该-v规则适用于所有搜索字词/模式。运行时,但不包括search term在结果中。

grep -i -E "search term" -ve "exclude term"

还有其他选项可以排除,因为有时我们必须在单词周围使用grep行,如果在下一个操作中使用'|'排除,,它只会删除该单词,但不会删除该单词的障碍
Learner

Answers:


40

使用grep 到表达式需要两个调用:

grep -Ei "search term" | grep -Eiv "exclude term"

如果您要搜索的术语不是正则表达式,请使用固定的字符串匹配(-F),这会更快:

grep -F "search term" | grep -Fv "exclude term"

18

除了两次调用grep之外,我只能想到一种方法来完成此任务。它涉及Perl兼容正则表达式(PCRE)和一些颇为怪异的环顾断言

要搜索排除包含bar的匹配项的foo,可以使用:

grep -P '(?=^((?!bar).)*$)foo'

运作方式如下:

  • (?!bar)匹配不禁止使用而不会消耗字符串字符的任何内容。然后.消耗一个字符。

  • ^((?!bar).)*从字符串(^)的开始到其结尾()重复上述操作$。如果bar在任何给定的点遇到它都会失败,因为(?!bar)不会匹配。

  • (?=^((?!bar).)*$) 确保字符串与先前的模式匹配,而不会消耗字符串中的字符。

  • foo照常搜索foo

我在正则表达式中发现了这种hack,以匹配不包含单词的字符串?。在Bart Kiers的答案中,您可以找到有关否定前瞻操作方式的详细说明。


不错的技巧。顺便说一句,这个技巧也适用于Java。
拉曼

12

如果要一次性完成此操作,可以使用awk代替grep。

格式:

echo "some text" | awk '/pattern to match/ && !/pattern to exclude/'

例子:

  • echo "hello there" | awk '/hello/ && !/there/'

不返回任何内容。

  • echo "hello thre" | awk '/hello/ && !/there/'

返回:hello thre

  • echo "hllo there" | awk '/hello/ && !/there/'

不返回任何内容。

对于多个模式,可以使用括号将它们分组。

例子:

  • echo "hello thre" | awk '(/hello/ || /hi/) && !/there/'

返回:hello thre

  • echo "hi thre" | awk '(/hello/ || /hi/) && !/there/'

返回:hi thre

  • echo "hello there" | awk '(/hello/ || /hi/) && !/there/'

不返回任何内容。

  • echo "hi there" | awk '(/hello/ || /hi/) && !/there/'

不返回任何内容。


1
它为我工作,但我迷失了颜色= P
Leopoldo Sanczyk

1
颜色从什么输出?如果您尝试使用ls保留颜色,则在解析输出时使用“ --color = always”参数(否则在解析文本时通常会总是丢失颜色)。示例: ls --color=always | awk '/hello/ && !/goodbye/'
菲利普·里斯

感谢@Philip的回答!我以前尝试过,但是没有成功。我猜因为该模式具有彩色文本,所以以后将不匹配,因此我应该在该模式中包含某种颜色代码。无论如何,您的方法是我发现grep -R使用Ubuntu命令行在多个代码文件中执行最快的方法。
Leopoldo Sanczyk

1

根据我的实验,如果您通过grep或传递排除条款,则不会有太大区别sed。Sed还有一些其他有用的文本替换功能,我经常使用它们来更好地过滤日志文件的输出。所以我将使用sed,因为我在sed上组合了许多过滤器。

wc /var/log/tomcat/tomcat.2013-01-14.log.1 
  1851725

 / usr / bin / time grep -i -E“(loginmanager)” /var/log/tomcat/tomcat.2013-01-14.log.1 | sed -e“ /登录成功/ d” -e“ /登录已过期/ d” | 厕所
24.05用户0.15系统0:25.27已使用95%CPU(0avgtext + 0avgdata 3504maxresident)k
0输入+0输出(0主要+246次)页面错误0交换
   5614 91168 1186298

 / usr / bin / time grep -i -E“(loginmanager)” /var/log/tomcat/tomcat.2013-01-14.log.1 | sed -e“ /登录成功/ d” -e“ /登录已过期/ d” | 厕所
23.50用户0.16系统0:24.48经过96%CPU(0avgtext + 0avgdata 3504maxresident)k
0输入+0输出(0主要+246次)页面错误0交换
   5614 91168 1186298

 / usr / bin / time grep -i -E“(loginmanager)” /var/log/tomcat/tomcat.2013-01-14.log.1 | grep -v -e“登录正常” -e“登录已过期” | 厕所
23.08用户0.14系统0:23.55已使用98%CPU(0avgtext + 0avgdata 3504maxresident)k
0输入+0输出(0主要+246次)页面错误0交换
   5614 91168 1186298

 / usr / bin / time grep -i -E“(loginmanager)” /var/log/tomcat/tomcat.2013-01-14.log.1 | grep -v -e“登录正常” -e“登录已过期” | 厕所
23.50用户0.15系统0:25.27已使用93%CPU(0avgtext + 0avgdata 3488maxresident)k
0输入+0输出(0主要+245次)页面故障0交换
   5614 91168 1186298


3
尝试比较grep -F代替的运行时,如果不需要grep -E,请不要使用-i
2013年

1
但是,然后您不提供使用sed;)的示例
本杰明·R
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.