我想找到有“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'。 然后您将知道它们同时出现在哪些文件中。

其他回答

我不知道如何用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文档:

grep搜索指定的输入FILEs(或标准输入,如果没有指定文件,或如果给出了一个连字符减号(-)作为文件名),以查找包含与给定PATTERN匹配的行。

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

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

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

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

用银搜索器:

ag 'abc.*(\n|.)*efg' your_filename

与戒指持有者的答案相似,但用ag代替。银色搜索者的速度优势可能在这里大放异彩。

你至少有几个选择

DOTALL方法

用(?s) DOTALL the。包含\n的字符 你也可以使用一个超前(?=\n)——不会在匹配中被捕获

example-text:

true
match me

false
match me one

false
match me two

true
match me three
third line!!
{BLANK_LINE}

命令:

grep -Pozi '(?s)true.+?\n(?=\n)' example-text

-p用于perl正则表达式

-o只匹配模式,而不是整行

-z允许换行

-i不区分大小写

输出:

true                                                  
match me                                              
true                                                  
match me three                                        
third line!!

注:

- +? makes modifier non-greedy so matches shortest string instead of largest (prevents from returning one match containing entire text)

你可以使用老式的O.G.手动方法,使用\n

命令:

grep -Pozi 'true(.|\n)+?\n(?=\n)'

输出:

true                                                  
match me                                              
true                                                  
match me three                                        
third line!!