使用 pcregrep grep 多行
Using pcregrep to grep multiple lines
我有一个具有以下模式的文件。
Foo $var1
.........
.........
Foo $var2
..........
..........
..........
Yes
我只想匹配以 "Foo" 开头并具有 "Yes" 的 "section"。 (您会注意到每个部分末尾都有一个空换行符)
预期的输出应该是。
Foo $var2
..........
..........
..........
Yes
我试过了
pcregrep -M "^Foo(.|\n)*^Yes"
但不幸的是,这从上一节开始匹配,并将倒数第二节与具有 "Yes" 的节合并为返回匹配项,因此我没有得到以 [= 开头的节28=] 并且有 "Yes" 但以 "Foo"
开头的部分与之前一样多
我的困境是如果在本节末尾我看不到 "Yes" 尽管我匹配了 "Foo".
如何丢弃之前的匹配
我尝试使用 lookbehind 函数,但它不能用于可变长度。
如果您使用启用了 PCRE 的 grep,将得到这样的结果
只是那些 Foo 带有 YES
请注意,我不确定 grep 是否会跨行。
可能,但我个人不知道。
(?m)^Foo\K(?:(?!^Foo)[\S\s])+(?=^Yes)
https://regex101.com/r/HCrcGO/1
展开
(?m)
^ Foo
\K
(?:
(?! ^ Foo )
[\S\s]
)+
(?= ^ Yes )
如果可以改用 gnu awk
,则可以使 awk
像这样在块模式下工作:
awk -v RS='Foo' -v ORS='' '/Yes/ {print RS[=10=]}' file
Foo $var2
..........
..........
..........
Yes
您可以从字符串的开头使用匹配 Foo,然后匹配所有不以 Yes 或 Foo 开头的行。
如果 Foo 和 Yes 不应该是更大单词的一部分,您可以使用单词边界 \b
^Foo\b.*(?:\n(?!Yes\b|Foo\b).*)*\nYes\b
部分
^
字符串开头
Foo\b.*
匹配 Foo 后跟除换行符之外的任何字符 0+ 次
(?:
非捕获组
\n
匹配换行符
(?!Yes\b|Foo\b)
否定前瞻,直接在右边断言not Yes或Foo
.*
匹配除换行符之外的任何字符 0+ 次
)*
关闭组重复0+次
\nYes\b
例如
pcregrep -Mo '^Foo\b.*(?:\n(?!Yes\b|Foo\b).*)*\nYes\b' file
输出
Foo $var2
..........
..........
..........
Yes
我有一个具有以下模式的文件。
Foo $var1
.........
.........
Foo $var2
..........
..........
..........
Yes
我只想匹配以 "Foo" 开头并具有 "Yes" 的 "section"。 (您会注意到每个部分末尾都有一个空换行符)
预期的输出应该是。
Foo $var2
..........
..........
..........
Yes
我试过了
pcregrep -M "^Foo(.|\n)*^Yes"
但不幸的是,这从上一节开始匹配,并将倒数第二节与具有 "Yes" 的节合并为返回匹配项,因此我没有得到以 [= 开头的节28=] 并且有 "Yes" 但以 "Foo"
开头的部分与之前一样多我的困境是如果在本节末尾我看不到 "Yes" 尽管我匹配了 "Foo".
如何丢弃之前的匹配我尝试使用 lookbehind 函数,但它不能用于可变长度。
如果您使用启用了 PCRE 的 grep,将得到这样的结果
只是那些 Foo 带有 YES
请注意,我不确定 grep 是否会跨行。
可能,但我个人不知道。
(?m)^Foo\K(?:(?!^Foo)[\S\s])+(?=^Yes)
https://regex101.com/r/HCrcGO/1
展开
(?m)
^ Foo
\K
(?:
(?! ^ Foo )
[\S\s]
)+
(?= ^ Yes )
如果可以改用 gnu awk
,则可以使 awk
像这样在块模式下工作:
awk -v RS='Foo' -v ORS='' '/Yes/ {print RS[=10=]}' file
Foo $var2
..........
..........
..........
Yes
您可以从字符串的开头使用匹配 Foo,然后匹配所有不以 Yes 或 Foo 开头的行。
如果 Foo 和 Yes 不应该是更大单词的一部分,您可以使用单词边界 \b
^Foo\b.*(?:\n(?!Yes\b|Foo\b).*)*\nYes\b
部分
^
字符串开头Foo\b.*
匹配 Foo 后跟除换行符之外的任何字符 0+ 次(?:
非捕获组\n
匹配换行符(?!Yes\b|Foo\b)
否定前瞻,直接在右边断言not Yes或Foo.*
匹配除换行符之外的任何字符 0+ 次
)*
关闭组重复0+次\nYes\b
例如
pcregrep -Mo '^Foo\b.*(?:\n(?!Yes\b|Foo\b).*)*\nYes\b' file
输出
Foo $var2
..........
..........
..........
Yes