如何使用JMESPath按名称选择JSON对象(Ansible场景)
如何使用JMESPath按名称选择对象?
在Ansible Playbook中,如何通过元素名称从JSON结构中提取指定元素?以下是具体场景:
当前Playbook代码
- debug: msg: "{{ test }}"
执行后输出的JSON数据
ok: [test] => { "msg": [ { "element1": { "test1": "test3", "test2": [ "1", "2", "3" ], "info": { "test4": "test", "test": 1, "test": "test" }, "test": "test", "test": "test", "test": "test", "test": "test" }, "element2": { "test": "test", "test": [ "test", "test" ], "test": { "test": "test", "test": 1, "test": "test", "test": 1 }, "test": "test", "test": "test", "test": "test", "test": "test" } } ] }
尝试的Playbook代码(未成功)
- name: Get item by name debug: msg="{{ my_json_file | json_query(jmesquery) }}" vars: jmesquery: "[?contains(@, `element2`)]"
期望输出
"element1": { "test1": "test3", "test2": [ "1", "2", "3" ], "info": { "test4": "test", "test": 1, "test": "test" }, "test": "test", "test": "test", "test": "test", "test": "test" }
解决方案
你之前的JMESPath查询错误,因为contains(@, 'element2')是检查对象是否包含某个值,而非是否存在指定键名。结合你的数据结构,这里提供两种可行的实现方式:
方式1:直接指定键名提取(最简单)
如果明确要提取的键是element1,直接通过路径访问即可。test变量对应输出里的msg数组,数组第一个元素就是包含目标键的对象,所以Playbook代码如下:
- name: 提取element1的值 debug: msg: "{{ test | json_query('[0].element1') }}"
如果需要保留element1作为键名(输出带键的完整对象),可以用投影构造:
- name: 提取带键名的element1 debug: msg: "{{ test | json_query('[0].{element1: element1}') }}"
方式2:按键名动态筛选(适用于不确定键名的场景)
如果需要通过判断键名来筛选(比如检查是否存在element1键),可以结合keys()和contains()函数实现:
- name: 动态筛选包含element1键的对象 debug: msg: "{{ test | json_query('[?contains(keys(@), `element1`)] | [0].element1') }}"
解释:
keys(@):获取当前对象的所有键名contains(keys(@), 'element1'):判断对象是否包含element1键[?...]:筛选数组中符合条件的元素| [0].element1:取筛选结果的第一个元素,提取其中的element1值
内容的提问来源于stack exchange,提问作者Veneomin
相关产品推荐
相关产品推荐

