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

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

应该匹配。


当前回答

用银搜索器:

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

在所有文件中递归搜索(在每个文件中的多行中),同时存在两个字符串(即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' * 

我不确定是否可以使用grep,但sed使它非常简单:

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

如果您愿意使用上下文,这可以通过输入来实现

grep -A 500 abc test.txt | grep -B 500 efg

这将显示“abc”和“efg”之间的所有内容,只要它们之间的距离不超过500行。

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

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

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