如何用SED/AWK/GREP过滤两模式间包含指定字符串的文本块
文本过滤实现方案
需求规则确认
- 起始匹配标记:
changed: - 结束边界判定:从
changed:开始计数,取第二个...作为当前文本块的结束位置 - 过滤逻辑:若
changed:到第二个...之间的内容包含replicas字符串,隐藏该段文本块,其余内容正常输出
实现方案
1. 正则替换方案
开启**单行匹配模式(点号匹配换行符)**后,使用以下正则匹配需要删除的文本块,将匹配结果替换为空即可:
changed:(?:(?!\.\.\.).)*\.\.\.(?:(?!\.\.\.).)*?replicas[\s\S]*?\.\.\.
正则逻辑说明:
- 先匹配起始标记
changed: - 匹配从
changed:到第一个...的所有内容,跳过第一个... - 向后扫描内容,若命中
replicas,则继续匹配到下一个(第二个)...为止 - 整个匹配到的块直接删除,即可过滤掉含
replicas的目标块
2. AWK脚本方案(更稳定,适合大文件处理)
编写独立AWK脚本实现逐行处理,避免正则多行匹配的兼容性问题:
BEGIN { in_changed_block = 0 dot_cnt = 0 block_buffer = "" contain_replicas = 0 } # 匹配到起始标记,进入块处理状态 /changed:/ { in_changed_block = 1 dot_cnt = 0 block_buffer = $0 "\n" contain_replicas = 0 next } # 处理块内内容 in_changed_block == 1 { block_buffer = block_buffer $0 "\n" # 检查是否包含目标字符串 if ($0 ~ /replicas/) contain_replicas = 1 # 计数...出现次数 if ($0 ~ /^\.\.\.$/) { dot_cnt++ # 到第二个...,块结束 if (dot_cnt == 2) { in_changed_block = 0 # 不含replicas才输出块内容 if (contain_replicas == 0) { printf "%s", block_buffer } block_buffer = "" next } } next } # 非块内内容直接输出 { print }
使用方法:
将脚本保存为filter.awk,执行以下命令输出结果:awk -f filter.awk 输入文件路径 > 输出文件路径
该方案完全匹配示例输入的输出要求,可直接使用。
内容的提问来源于stack exchange,提问作者enjoy343322434
相关产品推荐
相关产品推荐

