Ansible中基于正则过滤实现跨文件行插入的需求与问题
按规则合并文本行的解决方案
针对将/tmp/test1中不存在于/tmp/test2的行,按+ :后的内容分类追加到同类行末尾的需求,以下是基于awk的解决方法,可规避开头+ :导致的正则匹配问题:
核心思路
- 先读取
test2的所有行,记录已存在的行内容,同时按+ :后的分类键(字母开头、@开头、其他)分组存储行数据 - 读取
test1的行,仅处理test2中没有的行,按同样规则追加到对应分组 - 最后按顺序输出所有分组内容,覆盖原
test2文件
基础实现命令
awk ' BEGIN { FS = "+ :"; # 以"+ :"作为分隔符,直接提取分类键 } # 处理test2,记录已存在行和分组 NR == FNR { lines[$0] = 1; key = $2; if (key ~ /^[a-zA-Z]/) { alpha_groups[key] = alpha_groups[key] $0 "\n"; } else if (key ~ /^@/) { at_groups[key] = at_groups[key] $0 "\n"; } else { other_lines = other_lines $0 "\n"; } next; } # 处理test1,仅添加不存在的行 { if (!($0 in lines)) { key = $2; if (key ~ /^[a-zA-Z]/) { alpha_groups[key] = alpha_groups[key] $0 "\n"; } else if (key ~ /^@/) { at_groups[key] = at_groups[key] $0 "\n"; } else { other_lines = other_lines $0 "\n"; } } } # 输出最终内容 END { for (k in alpha_groups) printf "%s", alpha_groups[k]; for (k in at_groups) printf "%s", at_groups[k]; printf "%s", other_lines; } ' /tmp/test2 /tmp/test1 > /tmp/test2_new && mv /tmp/test2_new /tmp/test2
保持原有分类顺序的优化版本
如果需要保留test2中原有分类的出现顺序,可添加顺序记录逻辑:
awk ' BEGIN { FS = "+ :"; } NR == FNR { lines[$0] = 1; key = $2; if (key ~ /^[a-zA-Z]/) { if (!(key in alpha_order)) alpha_order[++alpha_cnt] = key; alpha_groups[key] = alpha_groups[key] $0 "\n"; } else if (key ~ /^@/) { if (!(key in at_order)) at_order[++at_cnt] = key; at_groups[key] = at_groups[key] $0 "\n"; } else { other_lines = other_lines $0 "\n"; } next; } { if (!($0 in lines)) { key = $2; if (key ~ /^[a-zA-Z]/) { if (!(key in alpha_order)) alpha_order[++alpha_cnt] = key; alpha_groups[key] = alpha_groups[key] $0 "\n"; } else if (key ~ /^@/) { if (!(key in at_order)) at_order[++at_cnt] = key; at_groups[key] = at_groups[key] $0 "\n"; } else { other_lines = other_lines $0 "\n"; } } } END { for (i=1; i<=alpha_cnt; i++) printf "%s", alpha_groups[alpha_order[i]]; for (i=1; i<=at_cnt; i++) printf "%s", at_groups[at_order[i]]; printf "%s", other_lines; } ' /tmp/test2 /tmp/test1 > /tmp/test2_new && mv /tmp/test2_new /tmp/test2
方案说明
- 通过设置
FS = "+ :"直接分割行内容,无需复杂正则匹配+ :,从根源避免了开头符号导致的正则过滤问题 - 用数组
lines记录已存在的行,确保仅添加test2中没有的内容 - 按分类键的开头类型分组,保证新行追加到对应分类的末尾
内容的提问来源于stack exchange,提问作者medisamm
相关产品推荐
相关产品推荐

