答案1
有多种方法可以做到这一点。这应该将执行的进程总数保持在最低限度:
find . -name \*.xml -print0 \ # List of *.xml files (NUL-terminated)
| xargs -0 grep -Zli 'string[12]' \ # is input to first grep, which sends (NUL-term'd)
| xargs -0 grep -Li 'string[34]' # file list to second grep
谢谢马特·吉布森提醒我们-Z
GNU grep 的标志。
答案2
你可以一次性完成所有操作find
,这样可以避免文件名中出现空格的问题。例如
find . -exec grep -liq "string1\|string2" {} \; -not -exec grep -liq "string3\|string4" {} \; -print
“-q” 抑制所有 grep 输出。-exec
当进程以 0 状态退出时,主进程返回 true,就像 grep 找到匹配项时所做的那样,而主-not
进程会反转这一点。因此,我们直接在 上放置两个条件find
,结果我们只打印满足这两个条件的文件名——无需管道!
答案3
正如我在评论中提到的那样,我认为您所缺少的是第一个 -Z 标志,grep
以及您在尝试的 -0 xargs
:
find . -name "*.xml" -exec grep -liZ "string1\|string2" {} \; | xargs -0 grep -Li "string3\|string4"
答案4
如果限制因素是 CPU(即您的磁盘速度很快)并且您拥有更多 CPU 核心,则可以使用 GNU Parallel:
find . -type f| parallel grep -Lq foo {} '||' grep -l bar {}
通过立即运行这两个grep
命令,文件可能仍在磁盘缓存中。如果磁盘寻道速度很慢,您可以添加-j1
以禁用并行性。
观看介绍视频以了解更多信息:http://www.youtube.com/watch?v=OpaiGYxkSuQ