我需要找到.php
不.pl
包含一个字符串(例如aaa
)但包含另一个字符串(例如bbb
)的文件。
我目前正在使用这个命令:
find /path/ \( -iname '*.php*' -or -name '*.pl*' \) -exec sh -c 'grep -l -v "aaa" {} | grep -l "bbb" {}' \; > resulttofile
要搜索大约一百万个文件,所以我想知道,
- 如果我的命令正常工作——一些眼睛采样给出了肯定的结果,
- 如果有可能变得更快(目前在 VM 上大约需要 2 分钟,但将添加更多文件)使用其他形式,或者
awk
代替sed
-grep
或者可能只是一个组合grep
而不是两个。
该系统是 Debian GNU/Linux。
您的命令无法正常工作:第一个
grep
将列出任何包含行不匹配的文件"aaa"
,第二个grep
将忽略第一个的输出,因为它有自己的文件要处理 - 因此您将获得匹配的文件列表"bbb"
,无论它们是否包含"aaa"
。grep
如果文件不包含任何行匹配"aaa"
(grep -L
),您需要要求仅列出文件,并xargs
用于处理生成的文件列表并仅将其提供给第二个文件grep
(或使第二个文件grep
以结果为条件)第一)。最重要的是,只要
find
列出的文件名不会对 shell 造成问题,它就可以工作——特别是,{}
直接包含在给定的命令中sh -c
意味着文件名最终可以被解释为 shell 命令(参见Is可以安全地使用 `find -exec sh -c` 吗?有关详细信息)。假设您使用的是 GNU,以下将需要更少的
grep
调用并且更安全grep
:运算
-or
符是 . 的 GNU 扩展find
。用于-o
便携性。未经测试,但这应该做我认为你想要的,使用 GNU awk
nextfile
和ENDFILE
上面一次只对多个文件调用 awk 一次,所以应该是高效的。
以上是如何在一个文件中匹配多个模式,然后在文件被完全读取后评估匹配组合的结果,但是正如@G-Man在评论中提到的“恢复莫妮卡”,你可以使它更有效率在这种特定情况下,如果/当匹配时停止读取当前文件,因为成功标准不存在:
aaa
aaa
您可以将多个 -exec 指令(或其他指令)与一个 find 命令链接在一起:
(换行只是为了适应 SE 的布局)。