如何用grep查找同时包含两个指定字符串的文件?
嘿,我有几个不用写bash循环脚本的方案帮你搞定这个需求——找到同时包含main(和foo的文件,比你原来的写法更简洁高效:
方案1:两次grep配合xargs(首推,通用又高效)
这是最直观且性能靠谱的方法,先筛出包含第一个模式的文件,再在这些文件里找第二个模式:
grep -rlF "main(" . | xargs grep -lF "foo"
- 解释下参数:
-F是按固定字符串匹配,避免(这类正则特殊字符被误解析;-r递归扫描子目录;-l只输出匹配到的文件名 xargs会把前一步的文件名批量传给第二个grep,比while read循环的效率更高,能减少进程创建的开销- 第二个
grep只在第一步筛选出的文件里找foo,最终输出同时满足两个条件的文件名
方案2:单grep搞定(依赖GNU grep)
如果你的系统用的是GNU grep(大多数Linux发行版默认都是),可以用Perl风格的正则实现单次扫描:
grep -rlP "(?s)(?=.*main\()(?=.*foo)" .
(?s)开启单行模式,让.能匹配换行符,这样整个文件内容会被当作一段连续文本处理(?=.*main\()和(?=.*foo)是正向预查,相当于同时做两个检查:文件里必须有main((注意转义(,因为它是正则特殊字符),也必须有foo,不管两个字符串的出现顺序- 只要两个条件都满足,就会输出对应的文件名
方案3:分支正则写法的单grep
另一种单grep的思路,直接匹配两种可能的顺序:
grep -rlP "(?s).*main\(.*foo|.*foo.*main\(" .
- 同样靠
(?s)开启单行模式 .*main\(.*foo匹配先出现main(再出现foo的文件,.*foo.*main\(则反过来匹配顺序相反的情况- 用
|把两种情况连起来,就能覆盖所有同时包含两个字符串的文件
验证示例
拿你提到的text1.txt来说:
int main() { stuff.... } foo
用上面任意一个命令都会输出text1.txt,完美符合你的需求。
内容的提问来源于stack exchange,提问作者laker93
相关产品推荐
相关产品推荐

