ChatGPT解决这个技术问题 Extra ChatGPT

使用 grep 进行负匹配(匹配不包含 foo 的行)

我一直在尝试制定此命令的语法:

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 通常不擅长负模式(除非引擎实现负前瞻)。

f
fedorqui

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?,总有办法:))
L
L0j1k

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

不包含 foo 的行:

awk '!/foo/'

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

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

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

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

等等。


这实际上很酷。您甚至不必学习完整的 awk 语言就可以将正则表达式与逻辑运算符组合在一起。感谢您的回答!
OP 特别要求 grep。为什么这被赞成?
P
Papa Smurf

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

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

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

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

虽然将使用 mmin 搜索在 60 mins 中修改的文件,但也使用 -type f,如此处所述 stackoverflow.com/a/33410471/2361131