如何使用grep查找包含一个模式但没有第二个模式的所有文件?

时间:2009-09-14 15:30:53

标签: shell grep

使用grep(或与其他标准命令行工具结合)是否有一种简单的方法来获取包含一个模式但没有第二个模式的所有文件的列表?

在我的具体情况中,我想要一个包含该模式的所有文件的列表:

override.*commitProperties

但不包含:

super.commitProperties

我在Windows上但是广泛使用cygwin。我知道如何找到第一个模式的所有文件或没有第二个模式的所有模式,但我不知道如何组合这些查询。

我更喜欢通用的答案,因为我感觉很多其他人都会觉得这种类型的查询很有用。这对我来说很容易采用通用解决方案并插入我的价值观。我只是包含了我的具体实例,以便于解释。

6 个答案:

答案 0 :(得分:10)

grep -rl "override.*commitProperties" . | xargs grep -L "super.commitProperties"

-l打印带匹配的文件

-L打印没有匹配的文件

答案 1 :(得分:4)

尝试

find . -print0 | xargs -0 grep -l "override.*commitProperties" \
| tr '\012' '\000' | xargs -0 grep -L super.commitProperties

tr命令会将换行符转换为ascii null,以便您可以在第二个xargs中使用-0,避免文件名中的空格等所有问题。

测试结果:

/tmp/test>more 1 2 3 | cat
::::::::::::::
1
::::::::::::::
override.*commitProperties
super.commitProperties
::::::::::::::
2
::::::::::::::
override.*commitProperties
::::::::::::::
3
::::::::::::::
hello world
/tmp/test>find . -print0 | xargs -0 grep -l "override.*commitProperties" | tr '\012' '\000' | xargs -0 grep -L super.commitProperties
./2
/tmp/test>

道格拉斯指出,发现+ xargs可以被grep -r替换。

答案 2 :(得分:2)

使用2个greps和comm的组合,如下所示(模式为A和B)。请注意,管道grep不起作用,因为模式可能在不同的行上。

$ cat a
A
$ cat b
B
$ cat ab
A
B

$ grep -l A * > A.only
$ grep -l B * > B.only  

$ comm -23 A.only B.only 
a

注意:comm命令打印两个文件共有或唯一的行。 “-23”打印第一个文件唯一的行 - 从而抑制第二个文件中的文件名。

答案 3 :(得分:2)

我的解决方案类似于Douglas Leeder,除了我不使用xargs:

grep -l 'override.*commitProperties' $(grep -L super.commitProperties *.txt)

grep -L 命令产品不包含模式 super.commitProperties 的文件列表, grep -l <​​/ strong>命令看起来对于该列表中的* override。 commitProperties 模式。

总的来说,这是一种不同的皮肤猫的方式。

答案 4 :(得分:1)

ack -l --make "override.*commitProperties" | xargs ack -L "super.commitProperties"

我使用了这个线程,并试图进行递归查找。这花费了25分钟+所以发现ack代替了。是在5分钟内完成的。

便利工具ack

答案 5 :(得分:0)

    grep "override.*commitProperties" *| grep -v "super.commitProperties" | cut -d":" -f1