【问题标题】:Negative matching using grep (match lines that do not contain foo)使用grep进行负匹配(匹配不包含foo的行)
【发布时间】:2022-12-14 07:12:49
【问题描述】:

如何使用grep匹配所有不匹配特定模式的行?我试过这个:

grep '[^foo]'

【问题讨论】:

  • [^error_log] 无论如何都不会工作,[] 是 char 类, regexp 通常不擅长否定模式(除非引擎实现否定先行)。

标签: regex grep


【解决方案1】:

grep -v 是你的朋友:

grep --help | grep invert  

-v, --invert-match 选择不匹配的行

另请查看相关的-L-l 的补充)。

-L, --files-without-match 只打印不包含匹配项的文件名

【讨论】:

  • 值得一提的是,对于多个(负)匹配项,可以使用 -e 选项:grep -v -e 'negphrase1' -e 'negphrase2'
  • 类似于@Babken-Vardanyan 的评论也 - 能够使用管道连接多个匹配项,例如grep -v 'negphrase1|negphrase2|negphrase3'
  • 最后的评论是不一样的,因为它会搜索不匹配两者而不是两者都不匹配的东西。即如果它匹配一个但不匹配另一个它仍然打印。用不相似的字符串尝试两种方法
  • @EvanLanglois - 使用-E 强制 grep 将模式解释为扩展正则表达式有效,即 grep -vE 'negphrase1|negphrase2|negphrase3'
  • @OlleHärstedt,我想我在之前的评论中误解了你的场景,以下可能是你要找的grep "" /dev/null * | grep foo | grep -v bar | cut -d: -f1 | sort -uwhy the first grep?,总有办法:))
【解决方案2】:

您也可以将 awk 用于这些目的,因为它允许您以更清晰的方式执行更复杂的检查:

不包含foo的行:

awk '!/foo/'

既不包含foo也不包含bar的行:

awk '!/foo/ && !/bar/'

既不包含foo也不包含bar但包含foo2bar2的行:

awk '!/foo/ && !/bar/ && (/foo2/ || /bar2/)'

等等。

【讨论】:

  • 这实际上很酷。您甚至不必学习完整的 awk 语言即可将正则表达式与逻辑运算符组合在一起。感谢您的回答!
  • OP 特别要求 grep。为什么要投票?
【解决方案3】:

在您的情况下,您可能不想使用 grep,而是向 find 命令添加一个否定子句,例如

find /home/baumerf/public_html/ -mmin -60 -not -name error_log

如果您想在名称中包含通配符,则必须将它们转义,例如排除后缀为 .log 的文件:

find /home/baumerf/public_html/ -mmin -60 -not -name *.log

【讨论】:

猜你喜欢
  • 2011-04-02
  • 2019-08-19
  • 2013-11-19
  • 1970-01-01
  • 2017-07-11
  • 1970-01-01
  • 2011-06-10
  • 2017-05-30
  • 2018-08-13
相关资源
最近更新 更多