我想找到有“abc”和“efg”的文件,这两个字符串在该文件中的不同行。一个包含以下内容的文件:

blah blah..
blah blah..
blah abc blah
blah blah..
blah blah..
blah blah..
blah efg blah blah
blah blah..
blah blah..

应该匹配。


当前回答

使用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 -lpne 'print $ARGV if /abc.*?efg/s' file_list

$ARGV包含从file_list读取当前文件时的文件名 /s修饰符跨换行搜索。

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

这应该可以工作:

cat FILE | egrep 'abc|efg'

如果有多个匹配项,可以使用grep -v过滤掉

虽然sed选项是最简单、最简单的,但遗憾的是,LJ的一行程序并不是最可移植的。那些受困于C Shell(而不是bash)版本的人将需要摆脱他们的刘海:

sed -e '/abc/,/efg/\!d' [file]

不幸的是,这一行在bash等中不起作用。