使用pcregrep来grep多行

时间:2019-09-13 19:10:41

标签: regex grep pcregrep

我有一个具有以下格式的文件。

Foo $var1
.........
.........

Foo $var2 
..........
..........
..........
Yes

我只想匹配以“ Foo”开头且为“是”的“部分”。 (您会注意到每个部分的末尾都有一个空换行符)

预期输出应该是

Foo $var2 
..........
..........
..........
Yes

我尝试了

  

pcregrep -M“ ^ Foo(。| \ n)* ^是”

但是不幸的是,这从上一部分开始匹配,并将倒数第二部分与以“是”作为返回匹配的部分混在一起,所以我没有一个以“ Foo”开头并具有“是”,但与以“ Foo”开头的部分一样多

我的难题是,如果在本节末尾我虽然匹配了“ Foo”却看不到“是”,则该如何放弃上一场比赛。

我尝试使用lookbehind函数,但不能用于可变长度。

3 个答案:

答案 0 :(得分:1)

您可以从字符串开头使用match Foo,然后匹配所有不是以Yes或Foo开头的行。

如果Foo和Yes不应该是较大单词的一部分,则可以使用单词边界\b

^Foo\b.*(?:\n(?!Yes\b|Foo\b).*)*\nYes\b

部分

  • ^字符串的开头
  • Foo\b.*匹配Foo,然后用0+乘除换行符以外的任意字符
  • (?:非捕获组
    • \n匹配换行符
    • (?!Yes\b|Foo\b)负向查找,在右边不直接断言Yes或Foo
    • .*匹配除换行符外的所有char 0次以上
  • )*关闭组并重复0次以上
  • \nYes\b

Regex demo

例如

pcregrep -Mo '^Foo\b.*(?:\n(?!Yes\b|Foo\b).*)*\nYes\b' file

输出

Foo $var2
..........
..........
..........
Yes

答案 1 :(得分:0)

如果您使用的是启用PCRE的grep,则类似这样的内容
那些带有 YES

Foo

请注意,我不确定grep是否会跨行。
可能是,但我个人不知道。

(?m)^Foo\K(?:(?!^Foo)[\S\s])+(?=^Yes)

https://regex101.com/r/HCrcGO/1

扩展

 (?m)
 ^ Foo
 \K 
 (?:
      (?! ^ Foo )
      [\S\s] 
 )+
 (?= ^ Yes )

答案 2 :(得分:0)

如果您可以改用gnu awk,则可以使awk像这样在块模式下工作:

awk -v RS='Foo' -v ORS='' '/Yes/ {print RS$0}' file
Foo $var2
..........
..........
..........
Yes