TL&DR

TL&DR

我一直在研究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

不可能同时使用-zwith ,因此,截至目前还没有可行的前瞻解决方案。-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}' ./*

相关内容