![如何使用两个输入文件中的行作为模式的开头和结尾来 grep 多个文件?](https://linux22.com/image/107465/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E4%B8%A4%E4%B8%AA%E8%BE%93%E5%85%A5%E6%96%87%E4%BB%B6%E4%B8%AD%E7%9A%84%E8%A1%8C%E4%BD%9C%E4%B8%BA%E6%A8%A1%E5%BC%8F%E7%9A%84%E5%BC%80%E5%A4%B4%E5%92%8C%E7%BB%93%E5%B0%BE%E6%9D%A5%20grep%20%E5%A4%9A%E4%B8%AA%E6%96%87%E4%BB%B6%EF%BC%9F.png)
我想编写一个简单的脚本,使用 grep 搜索文件列表。当前的代码看起来与此类似:
a= file1.txt
b= file2.txt
for
do
grep '$a.*$b' /root/listoffiles/*php >> found.txt
完毕
file1
和file2
都是单词列表。因此,这将搜索具有多个条件的目的地。例如,$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
,eins
和file2.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
同时包含one
和two
),那么您只需要两次 grep 调用:
grep -f file1.txt | grep -f file2.txt