我想找到有“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

其他回答

awk一行程序:

awk '/abc/,/efg/' [file-with-content]

随着几个月前ugrep的发布:

ugrep 'abc(\n|.)+?efg'

这个工具是高度优化的速度。它也是GNU/BSD/PCRE-grep兼容的。

注意我们应该使用惰性重复+?,除非您想将所有efg行匹配在一起,直到文件中的最后一个efg。

#!/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

在所有文件中递归搜索(在每个文件中的多行中),同时存在两个字符串(即string1和string2在不同的行中,并且都存在于同一个文件中):

grep -r -l 'string1' * > tmp; while read p; do grep -l 'string2' $p; done < tmp; rm tmp 

在所有文件中递归搜索(在每个文件中的多行中),使用EITHER字符串存在(即string1和string2在不同的行中,并且在同一个文件中存在):

grep -r -l 'string1\|string2' * 

我用它从一个multi fasta文件中提取一个fasta序列,使用grep的-P选项:

grep -Pzo ">tig00000034[^>]+"  file.fasta > desired_sequence.fasta

基于perl的搜索 Z表示行以0字节结尾,而不是换行字符 O来捕获匹配的内容,因为grep返回整行(在本例中,因为您做了-z是整个文件)。

regexp的核心是[^>],它翻译为“不大于符号”。