我想找到有“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..
应该匹配。
当前回答
你至少有几个选择
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!!
其他回答
使用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
我不知道如何用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 -l "pattern1" filepattern*.* | xargs grep "pattern2"
例子
grep -l "vector" *.cpp | xargs grep "map"
Grep -l将找到与第一个模式匹配的所有文件,xargs将为第二个模式查找Grep。希望这能有所帮助。
我在几天前发布了一个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上找到更多信息。
如果您愿意使用上下文,这可以通过输入来实现
grep -A 500 abc test.txt | grep -B 500 efg
这将显示“abc”和“efg”之间的所有内容,只要它们之间的距离不超过500行。