![什么 Linux 命令可以查找包含某些字符串但不包含其他字符串的文件?](https://linux22.com/image/1279425/%E4%BB%80%E4%B9%88%20Linux%20%E5%91%BD%E4%BB%A4%E5%8F%AF%E4%BB%A5%E6%9F%A5%E6%89%BE%E5%8C%85%E5%90%AB%E6%9F%90%E4%BA%9B%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%BD%86%E4%B8%8D%E5%8C%85%E5%90%AB%E5%85%B6%E4%BB%96%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E6%96%87%E4%BB%B6%EF%BC%9F.png)
答案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