我想使用 find 命令来查找一些同时包含多个模式的文件。
我试过这样的事情:
find . -name "*.xml" -exec grep -iH keyword1 + && grep -iH "keyword2" {} \;
Run Code Online (Sandbox Code Playgroud)
但是上面的命令不起作用。
是否可以在 bash 中做到这一点?
据我了解,您想列出同时包含“keyword1”和“keyword2”的文件。为此,您可以通过-exec以下方式使用两个测试:
find . -name "*.xml" -exec grep -iq keyword1 {} \; -exec grep -iH keyword2 {} \;
Run Code Online (Sandbox Code Playgroud)
这将grep有条件地运行第二个- 如果第一个返回 true。该-q选项会阻止第一个的输出grep,因为它会列出所有只包含“keyword1”的文件。
由于该-H选项将匹配行与文件名一起输出,因此您可能想-l改用它。所以
find . -name "*.xml" -exec grep -iq keyword1 {} \; -exec grep -il keyword2 {} \;
Run Code Online (Sandbox Code Playgroud)
这将产生与 Caleb 建议的类似的输出,但不需要额外的-print.
首先,要使用 find 执行此操作,您需要添加第二个-exec参数。每个参数只能运行一个命令。如果你需要运行多个东西,你必须通过将一个命令变成一个 shell 并运行多个命令来使用 hack。这是find做这项工作:
find . -name "*.xml" -exec grep -qi "keyword1" {} \; -exec grep -qi "keyword2" {} \; -print
Run Code Online (Sandbox Code Playgroud)
请注意,我使用 finds-print选项来输出文件名,而不是让 grep 执行它,并使用-qgrep 选项将其置于静默模式,以便它只提供一个返回码, find 可以使用它来判断结果是否为真假,然后继续。如果它到达最后一步(意味着两个文件都匹配),它会打印输出。
然而,这是低效的,因为 grep 实际上必须扫描所有文件两次。如果您的意思是字面上的问题,则必须这样做,但是如果您打算查找包含任何字符串的文件,则可以使用 grep 在一次传递中搜索这两种模式,如下所示:
find . -name "*.xml" -exec grep -qi -e "keyword1" -e "keyword2" {} \; -print
Run Code Online (Sandbox Code Playgroud)
编辑:在你的问题中不清楚你到底想要发生什么,我给出的两个例子实际上做了不同的事情。第一个是 AND 操作,只打印包含两个关键字的文件,第二个是 OR 操作,如果文件名包含任一字符串,则打印文件名。选择你的毒药。