如何使用两个输入文件中的行作为模式的开头和结尾来 grep 多个文件?

如何使用两个输入文件中的行作为模式的开头和结尾来 grep 多个文件?

我想编写一个简单的脚本,使用 grep 搜索文件列表。当前的代码看起来与此类似:

a= file1.txt 

b= file2.txt

for

do

grep '$a.*$b' /root/listoffiles/*php >> found.txt

完毕

file1file2都是单词列表。因此,这将搜索具有多个条件的目的地。例如,$a可以是“hello”和$b“world”,或者第二行可以是“red”和“tshirt”。如果它找到任何具有两个匹配条件的内容,那么它只会将其保存到文件中。我正在使用的循环不起作用并且效率不够。我只想获得符合标准的结果。有什么建议么?

答案1

你首先必须转义特殊字符在这两个文件(如果有)中,然后通过eg加入它们,paste最终得到一个模式列表,然后您可以使用viagrep-f...除非您有太多文件,否则不需要循环,因为grep可以接受多个论点:

paste -d'.*' <(sed 's/[.[\*^$]/\\&/g' file1.txt) /dev/null \
<(sed 's/[.[\*^$]/\\&/g' file2.txt) | grep -f - /root/listoffiles/*php >> found.txt

答案2

从单词列表中构建一个模式。从file1.txt包含 eg one, un,einsfile2.txt包含two, deux, zwei,您需要获取正则表达式(采用 ERE 语法)

(one|un|eins).*(two|deux|zwei)

如果单词列表不包含正则表达式中的任何特殊字符,那么您所需要做的就是用|(“或”运算符)替换换行符(最后一个除外)。

words1=$(tr '\n' '|' <file1.txt); words1=${words1%\|}
words2=$(tr '\n' '|' <file2.txt); words2=${words2%\|}
grep -E "($words1).*($words2)"

如果单词列表可能包含特殊字符,那么您需要引用它们。

words1=$(<file1.txt tr '\n' '|' | sed 's/[][\\().*?+|]/\\&/g'); words1=${words1%\|}
words2=$(<file2.txt tr '\n' '|' | sed 's/[][\\().*?+|]/\\&/g'); words2=${words2%\|}
grep -E "($words1).*($words2)"

请注意,如果您不关心单词的顺序并且可以接受重叠匹配(例如接受twone同时包含onetwo),那么您只需要两次 grep 调用:

grep -f file1.txt | grep -f file2.txt

相关内容