我想找到有“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..
应该匹配。
当前回答
如果你对你要找的两个字符串'abc'和'efg'之间的距离有一些估计,你可以使用:
grep -r . -e 'abc' -A num1 -B num2 | grep 'efg'
这样,第一个grep将返回'abc' + #num1行,后面是#num2行,第二个grep将筛选所有这些以获得'efg'。 然后您将知道它们同时出现在哪些文件中。
其他回答
使用ripgrep可以:
$ rg --multiline 'abc(\n|.)+?efg' test.txt
3:blah abc blah
4:blah abc blah
5:blah blah..
6:blah blah..
7:blah blah..
8:blah efg blah blah
或者其他咒语。
如果你愿意的话。作为换行符计算:
$ rg --multiline '(?s)abc.+?efg' test.txt
3:blah abc blah
4:blah abc blah
5:blah blah..
6:blah blah..
7:blah blah..
8:blah efg blah blah
或者等效于(?s)的是rg -multiline- multiline-dotall
为了回答最初的问题,它们必须在不同的行上:
$ rg——multiline 'abc.*[\n](\n|.)*efg' test.txt
如果你想让它“非贪婪”,这样你就不会用最后一个efg得到第一个abc(把它们分成成对):
$ rg——multiline 'abc.*[\n](\n|.)*?efg的用法
https://til.hashrocket.com/posts/9zneks2cbv-multiline-matches-with-ripgrep-rg
如果可以使用Perl,就可以很容易地做到这一点。
perl -ne 'if (/abc/) { $abc = 1; next }; print "Found in $ARGV\n" if ($abc && /efg/); }' yourfilename.txt
您也可以使用单个正则表达式来实现这一点,但这涉及到将文件的整个内容放入单个字符串中,对于大型文件,这可能会占用太多内存。 为了完整起见,下面是该方法:
perl -e '@lines = <>; $content = join("", @lines); print "Found in $ARGV\n" if ($content =~ /abc.*efg/s);' yourfilename.txt
文件模式*.sh对于防止目录被检查很重要。当然,一些测试也可以防止这种情况发生。
for f in *.sh
do
a=$( grep -n -m1 abc $f )
test -n "${a}" && z=$( grep -n efg $f | tail -n 1) || continue
(( ((${z/:*/}-${a/:*/})) > 0 )) && echo $f
done
The
grep -n -m1 abc $f
搜索最大1个匹配项并返回(-n)行数。 如果找到一个匹配(test -n…),找到efg的最后一个匹配(找到所有,并使用tail -n 1取最后一个匹配)。
z=$( grep -n efg $f | tail -n 1)
其他的继续。
由于结果类似于18:foofile.sh String alf="abc";我们需要从“:”开始切到行尾。
((${z/:*/}-${a/:*/}))
如果第二个表达式的最后一个匹配超过了第一个表达式的第一个匹配,则应返回正结果。
然后我们报告文件名echo $f。
下面是一种连续使用两个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等
如果你对你要找的两个字符串'abc'和'efg'之间的距离有一些估计,你可以使用:
grep -r . -e 'abc' -A num1 -B num2 | grep 'efg'
这样,第一个grep将返回'abc' + #num1行,后面是#num2行,第二个grep将筛选所有这些以获得'efg'。 然后您将知道它们同时出现在哪些文件中。