使用mikefarah/yq从YAML提取数据时值意外为null的问题
用yq提取指定格式的应用配置数据
原始配置文件(manifest.yml)
applications: a: enabled: true persistence: true b: enabled: true persistence: true c: enabled: true persistence: false
需求
提取所有enabled为true的应用,输出格式为应用名: persistence值的键值对集合,预期结果:
a: true, b: true, c: false
之前命令的问题
- 第一条命令语法错误:
yq '.applications | to_entries | .[] |select(.value.enabled == true) | .key: .value.persistence' manifest.yml
输出:
[{a: null}, {b: null}, {c: null}]
问题:直接写.key: .value.persistence无法正确构造键值对对象,yq无法识别该语法,导致值被默认设为null。
- 第二条命令多嵌套了不必要的层级:
yq '.applications | to_entries | .[] |select(.value.enabled == true) | {.key: {.persistence: .value.persistence}}' manifest.yml
输出:
a: null: true b: null: true c: null: false
问题:错误地在值层额外构造了以.persistence(解析为null)为键的对象,导致输出结构完全偏离预期。
正确解决方案
方案1:输出合并后的YAML对象
使用以下命令可得到合并为单个对象的标准YAML结果:
yq '.applications | to_entries | map(select(.value.enabled == true) | {(.key): .value.persistence}) | add' manifest.yml
输出:
a: true b: true c: false
方案2:输出逗号分隔的字符串(完全匹配预期格式)
如果需要严格匹配a: true, b: true, c: false的字符串格式,可结合yq和jq处理:
yq -o=json '.applications | to_entries | map(select(.value.enabled == true) | {(.key): .value.persistence}) | add' manifest.yml | jq -r 'to_entries | map("\(.key): \(.value)") | join(", ")'
输出:
a: true, b: true, c: false
命令逻辑说明
to_entries:将applications下的键值对转换为[{key: "应用名", value: {...}}, ...]的数组格式,方便后续筛选和构造新对象。map(select(...)):遍历数组,筛选出value.enabled为true的条目,同时构造以应用名为键、persistence值为值的独立对象。add:将多个独立对象合并为一个完整的键值对对象。- 方案2中用
-o=json将yq输出转为JSON格式,再通过jq将对象转换为条目数组,最终拼接成指定格式的字符串。
内容的提问来源于stack exchange,提问作者Andres Cabrera
相关产品推荐
相关产品推荐

