【问题标题】:Negative matching using grep (match lines that do not contain foo)使用 grep 进行负匹配(匹配不包含 foo 的行)
【发布时间】:2011-04-02 16:25:18
【问题描述】:

我一直在尝试找出这个命令的语法:

grep ! error_log | find /home/foo/public_html/ -mmin -60

或:

grep '[^error_log]' | find /home/baumerf/public_html/ -mmin -60

我需要查看除名为error_log 的文件之外的所有已修改文件。

I've read about it here,但只找到一个not-regex 模式。

【问题讨论】:

  • [^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 语言即可将正则表达式与逻辑运算符组合在一起。感谢您的回答!
【解决方案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

【讨论】:

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