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

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

应该匹配。


当前回答

你至少有几个选择

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

其他回答

用银搜索器:

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

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

Grep是这种操作的笨拙工具。

在大多数现代Linux系统中都可以找到pcregrep,可以用作

pcregrep -M  'abc.*(\n|.)*efg' test.txt

where -M,——multiline允许模式匹配多行

还有一个更新的pcre2grep。两者都是由PCRE项目提供的。

pcre2grep可以通过Mac Ports作为pcre2端口的一部分用于Mac OS X:

% sudo port install pcre2 

并通过Homebrew为:

% brew install pcre

或者pcre2

% brew install pcre2

pcre2grep在Linux (Ubuntu 18.04+)上也可用

$ sudo apt install pcre2-utils # PCRE2
$ sudo apt install pcregrep    # Older PCRE

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

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

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

遗憾的是,你不能。来自grep文档:

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

我在几天前发布了一个grep替代方案,它直接支持这一点,通过多行匹配或使用条件——希望它对搜索这里的人有用。下面是示例命令的样子:

多行:

sift -lm 'abc.*efg' testfile

条件:

sift -l 'abc' testfile --followed-by 'efg'

你也可以指定'efg'必须在一定的行数内跟在'abc'后面:

sift -l 'abc' testfile --followed-within 5:'efg'

你可以在sift-tool.org上找到更多信息。