You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

awk中行尾与记录尾区分:匹配行尾数字输出指定段落

问题描述

需要匹配行尾为数字200(用$锚定)的段落,忽略第三段。数据如下:

this is first paragraph
number 200
with some text

this is second paragraph
with some text
number 200

this is third paragraph
with some text
number 2001

使用awk -v RS="" -v ORS="\n\n" "/number 200\n/" file仅匹配第一段;使用awk -v RS="" -v ORS="\n\n" "/number 200$/" file仅匹配第二段——问题在于awk将$识别为**记录尾(段落尾)**而非行尾。现在需要在无原生段落处理支持的grep中,优雅解决这个问题,预期输出:

this is first paragraph
number 200
with some text

this is second paragraph
with some text
number 200
解决方案

可以结合grep的多选项与PCRE正则实现需求,以下是两种可行方案:

方案1:使用标准grep(支持-z/-P选项)

grep -zPo '(?s)(^|\n\n)(.*?number 200\n.*?)(?=\n\n|\z)' file | tr '\0' '\n'

命令细节解释

  • -z:将整个文件视为单个连续流(用NUL字符作为记录分隔符),突破grep默认按行处理的限制。
  • -P:启用Perl兼容正则表达式,支持单行模式、正向预查等高级特性。
  • -o:仅输出匹配到的目标内容,而非整文件/整行。
  • 正则规则:
    • (?s):开启单行模式,让.可以匹配换行符,实现跨多行的段落匹配。
    • (^|\n\n):匹配段落起始位置——要么是文件开头,要么是两个换行符(段落分隔标记)。
    • (.*?number 200\n.*?):非贪婪匹配段落内容,确保包含行尾为200的行(number 200\n避免误匹配2001这类后缀)。
    • (?=\n\n|\z):正向预查段落结束位置——要么是下一个段落的分隔符(两个换行符),要么是文件结尾。
  • tr '\0' '\n':将grep-z模式输出的NUL字符转换回换行符,恢复正常格式。

方案2:使用pcregrep(专门PCRE工具)

如果你的环境中有pcregrep,命令更简洁:

pcregrep -M '(^|\n\n).*?number 200\n.*?(?=\n\n|\z)' file

-M选项直接允许正则表达式跨多行匹配内容,无需额外处理流格式。

内容的提问来源于stack exchange,提问作者user3602441

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 11:00:59