如何使用awk/sed/bash按模式文件删除YAML行与块 解决命令仅匹配首个模式问题
YAML规则化删除的awk实现方案
工具使用约束
- 仅可使用awk、bash、sed三类工具,禁止引入perl、python、ruby及相关第三方库
- 匹配规则全部从独立存储的模式文件读取,无需硬编码到处理逻辑中
- 需支持两类差异化删除动作,不混淆规则类型
原有命令的核心缺陷
原先编写的测试命令逻辑存在两处明显问题,导致无法覆盖全量规则:
- 未对模式文件做预处理,文件中的注释行、空行也会被当成匹配规则,极易造成YAML内容误删
- 逻辑未做规则类型区分,仅实现了基础的正则匹配行打印,既没有处理缩进块的连续删除逻辑,也会因为循环判断的早退机制,漏处理部分规则
规则分类说明
模式文件内的规则按删除动作分为两类:
- 整行删除规则:只要当前YAML行包含规则字符串,就删除该整行,对应匹配项为
kubectl.kubernetes.io/last-applied-configuration、openshift.io/backup-registry-hostname - 缩进块删除规则:匹配到规则字符串时,删除当前行及所有比当前行缩进深度更大的连续关联代码块,直到遇到缩进深度小于等于当前行的位置才恢复打印,对应匹配项为
managedFields、status
参考模式文件内容
#Remove the entire yaml line for the following kubectl.kubernetes.io/last-applied-configuration openshift.io/backup-registry-hostname #remove the entire yaml block for the following managedFields status
参考待处理YAML内容
apiVersion: v1 items: - apiVersion: apps.openshift.io/v1 metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"apps.openshift.io/v1","kind":"DeploymentConfig","metadata":{"annotations":{"openshift.io/backup-registry-hostname":"docker-registry.default.svc:5000",,"spec":} openshift.io/backup-registry-hostname: docker-registry.default.svc:5000 status: ingress: - conditions: metadata: selfLink: ""
完整可执行处理逻辑
将以下awk代码保存为脚本或直接执行,传入模式文件路径和目标YAML路径即可完成全部删除操作:
awk ' # 第一阶段:读取模式文件,按规则类型分类存储 NR == FNR { # 跳过空行 if ($0 ~ /^[[:space:]]*$/) next # 识别规则分类标记 if ($0 ~ /Remove the entire yaml line/) { rule_type = "line"; next } if ($0 ~ /remove the entire yaml block/) { rule_type = "block"; next } # 非标记行按类型存入对应规则数组 if (rule_type == "line") line_del[$0] = 1 if (rule_type == "block") block_del[$0] = 1 next } # 第二阶段:逐行处理目标YAML { # 计算当前行的前导空格数,作为缩进深度值 match($0, /^[[:space:]]*/) current_indent = RLENGTH # 块删除状态判断:遇到缩进浅于触发块的行时,恢复打印 if (deleting_block && current_indent <= block_indent) { deleting_block = 0 } # 处于块删除区间时直接跳过当前行 if (deleting_block) next # 检查是否命中整行删除规则 skip_line = 0 for (pat in line_del) { if ($0 ~ pat) { skip_line = 1 break } } if (skip_line) next # 检查是否命中块删除规则,触发块删除状态 for (pat in block_del) { if ($0 ~ pat) { block_indent = current_indent deleting_block = 1 skip_line = 1 break } } if (skip_line) next # 未命中任何删除规则,打印当前行 print $0 } ' patterns target_yaml_file
输出效果验证
对上述样例YAML执行处理后,最终输出符合预期:
apiVersion: v1 items: - apiVersion: apps.openshift.io/v1 metadata: annotations: metadata: selfLink: ""
处理逻辑会自动删除两个注解对应的整行,以及整个status关联的缩进块(包含ingress、conditions等下属行)。
内容的提问来源于stack exchange,提问作者JRC2020
相关产品推荐
相关产品推荐

