如何使用jq通过子节点属性值匹配获取对应父键名
问题场景
现有如下JSON格式的监控告警配置数据:
{ "Server monitoring - Disk, Memory, CPU": { "alerts": { "d_usage_65": { "title": "D Usage 65 | #site" }, "d_usage_75": { "title": "D Usage 75 | #site" } } }, "Categoty 2": { "alerts": { "thread_count_50": { "title": "Thread Count above 50 | #site" }, "upload_manager_thread_count_100": { "title": "Thread Count above 100 | #site" } } } }
需求:输入指定title值D Usage 65 | #site时,获取其对应的父级键名d_usage_65。
此前尝试使用的jq命令如下:
.[] | .alerts | select(.[].title == "D Usage 65 | #aidoc_site") | keys
执行后返回了alerts节点下的所有键,不符合预期:
[ "d_usage_65", "d_usage_75" ]
错误原因
原命令存在两个问题:
- 匹配的目标title值写错了,实际要匹配的是
D Usage 65 | #site,命令中误写为D Usage 65 | #aidoc_site - 筛选逻辑层级错误:
select(.[].title == "xxx")的判断逻辑是「当前alerts对象下是否存在任意子项的title匹配目标值」,只要有一个子项命中,就会选中整个alerts对象,后续调用keys自然会返回alerts下的所有键,无法定位到单个匹配的子项。
正确实现方案
使用to_entries将alerts对象转换为键值对结构的数组,遍历数组筛选出value中title匹配目标值的项,直接输出对应的key即可:
.[] | .alerts | to_entries[] | select(.value.title == "D Usage 65 | #site") | .key
执行后返回带引号的结果:
"d_usage_65"
如果需要输出无引号的原始字符串,调用jq时加上-r参数即可:
jq -r '.[] | .alerts | to_entries[] | select(.value.title == "D Usage 65 | #site") | .key' 你的json文件路径
执行输出:
d_usage_65
内容的提问来源于stack exchange,提问作者Rom Kimchi
相关产品推荐
相关产品推荐

