如何使用yq/jq按map文件结构原地更新合并两个YAML文件
实现方案
完全可以通过yq实现该需求,推荐使用mikefarah/yq v4+版本,无需依赖jq即可动态适配任意结构的YAML文件,严格按照map文件定义的键结构从data文件取值,自动丢弃map中未定义的键。
执行命令
将data.yaml和map.yaml放在同一目录下,执行以下命令即可得到预期结果:
yq ' def filter_by_map($data; $map): $map | with_entries( .key as $k | .value as $map_val | ($data | .[$k]) as $data_val | if $map_val == null then .value = $data_val elif ($map_val | type) == "!!map" then .value = filter_by_map($data_val; $map_val) else .value = $data_val end ); filter_by_map(load("data.yaml"); load("map.yaml")) ' -n
处理逻辑
- 递归遍历
map.yaml中定义的所有键路径,不会额外引入map中不存在的键 - 若map中某个键写为
key:格式(后面无内容、无嵌套子键,值为null),直接取data.yaml中对应键的完整值填入,保留该键下所有子结构 - 若map中某个键存在嵌套子键,则递归进入子键层级做同样的匹配过滤,仅保留map中明确定义的子键
- 所有map中不存在的键(无论顶级还是任意嵌套层级)全部丢弃
输出结果
执行命令后输出结构与预期完全一致:
data1: subkey1: subvalue1 subkey2: subvalue2 data3: subkey3: subvalue3
补充说明
- 该方案不需要提前固定YAML的键路径,可直接适配动态变化的文件内容,支持任意深度的嵌套结构
- 若你使用的是旧版基于Python的py-yq(依赖jq的早期实现),上述语法不兼容,建议升级到mikefarah/yq v4+版本使用
- 如果必须使用jq实现,需要先将两个YAML文件转为JSON格式,复用上述递归过滤逻辑处理后再转回YAML,流程更繁琐,无特殊需求不推荐
内容的提问来源于stack exchange,提问作者Arockiasmy K
相关产品推荐
相关产品推荐

