查找其中包含 2 個術語的文本文件(以任何順序,在任何行)
我一直在查看
grep -e
您在哪裡進行“與”操作,這是我想要的那種事情。但是,如果我做對了,這兩個術語必須在同一行才能返回。相反,我感興趣的是在一個目錄中找到我所有的文件,其中包含兩個術語,可能在不同的行上。如果順序很重要,我確實知道一個術語總是會出現在另一個之前,但是當然可以使用通用解決方案。
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
但前提是這兩個術語在同一行
-z
也可以使用 GNU grep選項使整個文件充當一個文件(如果文件不包含 NUL。Unix 文本文件不包含) :grep -zE '(TermOne.*TermTwo)|(TermTwo.*TermOne)' file
It is not possible to use
-z
with-P
at the same time, so, no lookahead solutions possible as of today.The other alternative is to grep twice:
<file grep 'TermOne' | grep -q 'TermTwo'
The exit code of the whole pipe will signal
0
only if both terms were found in one file.Or, to use 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
list files
The first two solutions from above will work to recursively list all files by adding the options
-r
(recursive, which then there is no need for a filename) and-l
(list matching filenames).grep -rlzE '(TermOne.*TermTwo)|(TermTwo.*TermOne)'
Or, using find (two grep calls):
find . -type f -exec grep -q 'TermOne' {} \; -exec grep -q 'TermTwo' {} \; -print
Or, using awk (the glob will include only the 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}' ./*