grep 表示“术语”并排除“另一个术语”

nel*_*aro 40 linux search bash grep

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

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

grep -i -E "search term" -ev "exclude term"
grep: exclude term: No such file or directory
Run Code Online (Sandbox Code Playgroud)

在我看来,这-v适用于所有搜索词/模式。由于此运行但随后不包含search term在结果中。

grep -i -E "search term" -ve "exclude term"
Run Code Online (Sandbox Code Playgroud)

Tho*_*hor 48

为了使用grep表达式,你需要两个调用:

grep -Ei "search term" | grep -Eiv "exclude term"
Run Code Online (Sandbox Code Playgroud)

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

grep -F "search term" | grep -Fv "exclude term"
Run Code Online (Sandbox Code Playgroud)


Den*_*nis 22

除了两次调用 grep 之外,我只能想到一种方法来完成此操作。它涉及Perl 兼容正则表达式(PCRE) 和一些相当hacky的环视断言

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

grep -P '(?=^((?!bar).)*$)foo'
Run Code Online (Sandbox Code Playgroud)

这是它的工作原理:

  • (?!bar)匹配任何不bar 的东西,而不消耗字符串中的字符。然后.消耗单个字符。

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

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

  • foo像往常一样搜索foo

我在正则表达式中发现了这个 hack来匹配不包含单词的字符串?. 在Bart Kiers 的回答中,您可以找到有关负面预测如何运作的更详细的解释。


小智 15

如果您想一次性完成此操作,您可以使用 awk 而不是 grep。

格式:

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

例子:

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

什么都不返回。

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

返回:你好三

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

什么都不返回。

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

例子:

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

返回:你好三

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

返回: 嗨三

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

什么都不返回。

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

什么都不返回。