我想找到有“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”的文件,这两个字符串在该文件中的不同行。一个包含以下内容的文件:
blah blah..
blah blah..
blah abc blah
blah blah..
blah blah..
blah blah..
blah efg blah blah
blah blah..
blah blah..
应该匹配。
当前回答
这可以通过首先使用tr用其他字符替换换行符来轻松完成:
tr '\n' '\a' | grep -o 'abc.*def' | tr '\a' '\n'
这里,我使用警报字符\a (ASCII 7)来代替换行符。 这在你的文本中几乎找不到,而且grep可以用一个.匹配它,或者专门用\a匹配它。
其他回答
我不知道如何用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的方法:
egrep -o 'abc|efg' $file | grep -A1 abc | grep efg | wc -l
返回0或正整数。
egrep -o(只显示匹配,技巧:同一行上的多个匹配会产生多行输出,就好像它们在不同的行上一样)
grep -A1 abc(打印abc及其后面的行) Grep efg | wc -l(在ABC之后的相同或后面的行中发现的efg行数为0-n,结果可用于'if") 如果需要模式匹配,可以将Grep更改为egrep等
使用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
sed应该足够了,就像海报LJ上面说的,
而不是!d,你可以简单地使用p打印:
sed -n '/abc/,/efg/p' file
遗憾的是,你不能。来自grep文档:
grep搜索指定的输入FILEs(或标准输入,如果没有指定文件,或如果给出了一个连字符减号(-)作为文件名),以查找包含与给定PATTERN匹配的行。