如何使用yq实现两个YAML文档覆盖合并且数组元素匹配更新
问题原因
你之前使用的*+合并逻辑是YQ的默认数组合并策略,仅支持全量追加数组元素,不会对元素的directory字段做匹配关联,因此会出现元素重复或者未匹配元素丢失的问题。
正确合并命令
以下为适配YQ v4版本的实现命令,可实现按directory字段匹配合并数组:
yq eval-all ' # 分别读取两个文件的include数组 (select(fi == 0).include) as $base_include | (select(fi == 1).include) as $overlay_include # 基于base文件做修改 | select(fi == 0) | .include = ( # 处理base已有元素:匹配到overlay同directory项则合并属性 ($base_include | map( .directory as $current_dir | $overlay_include[] | select(.directory == $current_dir) as $matched | if $matched then . * $matched else . end )) # 追加overlay独有的元素 + ($overlay_include | map(select(.directory as $overlay_dir | $base_include[].directory != $overlay_dir))) ) ' base.yaml overlay.yaml
命令逻辑说明
- 内置变量
fi为YQ的文件索引标识,fi==0对应第一个输入文件base.yaml,fi==1对应第二个输入文件overlay.yaml - 先遍历base的
include数组,对每个元素用directory字段匹配overlay的元素,匹配成功则用*运算合并overlay的新增属性,未匹配则保留原元素 - 最后筛选出overlay中
directory未在base中出现的独有元素,追加到数组末尾
输出验证
执行上述命令后输出的结果完全符合预期:
include: - directory: foo/foo1 extra: true stuff: stuff1: true stuff2: true - directory: bar/bar1 - directory: something/else
内容的提问来源于stack exchange,提问作者user17519154
相关产品推荐
相关产品推荐

