我一直在研究grep -e
你在哪里进行“与”操作,这正是我想要的。但是,如果我做对了,这两个术语必须位于同一行才能返回。
我感兴趣的是找到目录中包含这两个术语的所有文档,可能位于不同的行。如果顺序很重要,我确实知道一个术语总是出现在另一个术语之前,但是当然通用解决方案就可以了。
答案1
TL&DR
笔记: 你必须自己测试一下哪一个最快。
grep -rlzE '(TermOne.*TermTwo)|(TermTwo.*TermOne)'
find . -type f -exec grep -q 'TermOne' {} \; \
-exec grep -q 'TermTwo' {} \; \
-print
awk '/TermOne/{if(p==0)p=1; if(p==2)p=3}
/TermTwo/{if(p==0)p=2; if(p==1)p=3}
p==3{print FILENAME;p=0;nextfile}' ./*
一个文件
无法构建可以匹配文件中两个单独字符串的正则表达式。
可以使用任一交替搜索两个术语:
grep -E '(TermOne.*TermTwo)|(TermTwo.*TermOne)' file
或前瞻:
grep -P '(?=.*TermOne)(?=.*TermTwo)' file
但前提是这两项是在同一条线上
还可以使用 GNU grep-z
选项使整个文件充当一个文件(如果该文件不包含 NUL。Unix 文本文件不包含):
grep -zE '(TermOne.*TermTwo)|(TermTwo.*TermOne)' file
不可能同时使用-z
with ,因此,截至目前还没有可行的前瞻解决方案。-P
另一种选择是 grep 两次:
<file grep 'TermOne' | grep -q 'TermTwo'
0
仅当在一个文件中找到这两个术语时,整个管道的退出代码才会发出信号。
或者,使用 awk:
awk '/TermOne/{if(p==0)p=1; if(p==2)p=3}
/TermTwo/{if(p==0)p=2; if(p==1)p=3}
p==3{print "both terms found"; exit}' file
列出文件
上面的前两个解决方案将通过添加选项-r
(递归,然后不需要文件名)和-l
(列出匹配的文件名)来递归地列出所有文件。
grep -rlzE '(TermOne.*TermTwo)|(TermTwo.*TermOne)'
或者,使用 find (两个 grep 调用):
find . -type f -exec grep -q 'TermOne' {} \; -exec grep -q 'TermTwo' {} \; -print
或者,使用 awk(glob 将仅包含 PWD):
awk '/TermOne/{if(p==0)p=1; if(p==2)p=3}
/TermTwo/{if(p==0)p=2; if(p==1)p=3}
p==3{print FILENAME;p=0;nextfile}' ./*