多行上的 sed 正则表达式无法捕获所有
Posted
技术标签:
【中文标题】多行上的 sed 正则表达式无法捕获所有【英文标题】:sed regex on multiple line can't capture all 【发布时间】:2021-10-07 15:35:30 【问题描述】:我有这个文本文件(示例)
<This is a line of text with a year=2020 month=12 in it
This line of text does not have a year or month in it
This year=2021 is the current year the current month=1
This is the year=2021 the month=2/>
<This is a line of text with a year=33020 month=12 in it
This line of text does not have a year or month in it
This year=33020 is the current year the current month=1
This is the year=33020 the month=2/>
使用 linux sed (sed (GNU sed) 4.2.2) 正则表达式:
sed -En 'N;s/\<(This.*2020.*[\s\S\n]*?)\>/\1/gp' test2.txt
它只捕获这个字符串:
<This is a line of text with a year=2020 month=12 in it
This line of text does not have a year or month in it
我尝试将 之间的第一段捕获为组
我在这里做错了什么?
【问题讨论】:
难道\<
和\>
有时也用作单词分隔符?
你这是什么意思?
我的意思是 GNU sed 正则表达式使用 \<
和 \>
作为单词的开始和结束分隔符。
【参考方案1】:
如果您想打印以<This
开头、包含2020
且仅包含它们的段落(由<...>
分隔),您可以尝试:
sed -En '/^</!d;:a;/>$/!N;ba;;/<This.*2020/p;' test2.txt
只要模式空间不以<
开头,就会被删除并开始一个新的循环(/^</!d
)。
然后,只要模式空间不以>
结尾,就会追加新行,但不会开始新的循环,而是跳转到a
标签(/>$/!N;ba;
)。
当整个段落存储在模式空间中时,我们退出此循环并应用最后一个命令 (^<This.*2020/p
):如果模式空间与您的模式匹配,则将其打印。终于,一个新的循环开始了。
当然,正则表达式必须适应您的需要。如果段落分隔符可以在空格之前(之后),例如,使用:
sed -En '/^[[:space:]]*</!d;:a;/>[[:space:]]*$/!N;ba;;/<This.*2020/p;' test2.txt
【讨论】:
我用这个命令修复了它: sed -i -En '/./H;$!d ; X ; s///p' test2.txt 但现在我有新问题要检查? unix.stackexchange.com/questions/662974/…【参考方案2】:使用 GNU Awk,您可以将 RS
指定为正则表达式。
bash gawk -v RS='[<>]' /This.*2020/ <<\:
> <This is a line of text with a year=2020 month=12 in it This line of
> text does not have a year or month in it This year=2021 is the current
> year the current month=1 This is the year=2021 the month=2/>
>
> <This is a line of text with a year=33020 month=12 in it This line of
> text does not have a year or month in it This year=33020 is the
> current year the current month=1 This is the year=33020 the month=2/>
> :
This is a line of text with a year=2020 month=12 in it
This line of text does not have a year or month in it
This year=2021 is the current year the current month=1
This is the year=2021 the month=2/
如您所见,这也会修剪分隔符;但添加回来并不难(提示: print "<" $0 ">"
)。
【讨论】:
以上是关于多行上的 sed 正则表达式无法捕获所有的主要内容,如果未能解决你的问题,请参考以下文章