我想找到有“abc”和“efg”的文件,这两个字符串在该文件中的不同行。一个包含以下内容的文件:
blah blah..
blah blah..
blah abc blah
blah blah..
blah blah..
blah blah..
blah efg blah blah
blah blah..
blah blah..
应该匹配。
我想找到有“abc”和“efg”的文件,这两个字符串在该文件中的不同行。一个包含以下内容的文件:
blah blah..
blah blah..
blah abc blah
blah blah..
blah blah..
blah blah..
blah efg blah blah
blah blah..
blah blah..
应该匹配。
当前回答
sed应该足够了,就像海报LJ上面说的,
而不是!d,你可以简单地使用p打印:
sed -n '/abc/,/efg/p' file
其他回答
#!/bin/bash
shopt -s nullglob
for file in *
do
r=$(awk '/abc/{f=1}/efg/{g=1;exit}END{print g&&f ?1:0}' file)
if [ "$r" -eq 1 ];then
echo "Found pattern in $file"
else
echo "not found"
fi
done
我不知道如何用grep做到这一点,但我会用awk做这样的事情:
awk '/abc/{ln1=NR} /efg/{ln2=NR} END{if(ln1 && ln2 && ln1 < ln2){print "found"}else{print "not found"}}' foo
不过,你需要注意如何做到这一点。您希望正则表达式匹配子字符串还是整个单词?适当添加\w标记。此外,虽然这严格符合您陈述的示例,但当abc在efg之后第二次出现时,它并不完全有效。如果你想处理这个问题,在/abc/ case等中添加一个If。
下面是一种连续使用两个grep的方法:
egrep -o 'abc|efg' $file | grep -A1 abc | grep efg | wc -l
返回0或正整数。
egrep -o(只显示匹配,技巧:同一行上的多个匹配会产生多行输出,就好像它们在不同的行上一样)
grep -A1 abc(打印abc及其后面的行) Grep efg | wc -l(在ABC之后的相同或后面的行中发现的efg行数为0-n,结果可用于'if") 如果需要模式匹配,可以将Grep更改为egrep等
用银搜索器:
ag 'abc.*(\n|.)*efg' your_filename
与戒指持有者的答案相似,但用ag代替。银色搜索者的速度优势可能在这里大放异彩。
下面是一个受到这个答案启发的解决方案:
如果'abc'和'efg'可以在同一行: Grep -zl 'abc。*efg' <您的文件列表> 如果'abc'和'efg'必须在不同的行上: grep -Pzl '(?s)abc.*\n.;*efg' <您的文件列表>
参数:
-P使用perl兼容的正则表达式。 将输入视为一组行,每一行以0字节结束,而不是换行符。例如,grep将输入视为一行。注意,如果你不使用-l,它将显示匹配后的NUL字符,见注释。 -l list只匹配文件名。 (?s)激活PCRE_DOTALL,这意味着'。'查找任何字符或换行符。