Ansible中json_query的contains过滤器未正确过滤flags数据问题
问题描述
我需要过滤如下结构的数据:
"flags": [ "inhibitor" ], ......(部分数据省略).... "flags": [], ......(其他数据省略)... "flags": [],
预期返回仅包含"inhibitor"的flags数组,即:
ok: [localhost] => { "msg": [ [ "inhibitor" ] ] }
但使用以下Ansible代码后,返回了所有flags数组(包括空数组):
- name: Set appropriate facts based on the report set_fact: leapp_preupgrade_report_inhibitors: > {{ leapp_preupgrade_report["entries"] | json_query("[*].flags[?contains(@, 'inhibitor')]") | list }} - debug: msg: "{{ leapp_preupgrade_report_inhibitors }}"
也尝试了以下写法,但仍未解决:
{{ leapp_preupgrade_report["entries"] | to_json |from_json | json_query("[*].flags[?contains(@, 'inhibitor')]") | list }}
请问如何正确过滤出所需的flags列表?
解决方案
问题出在当前的JSONPath查询会遍历所有entries的flags字段,即便flags为空或不包含inhibitor,也会返回空数组,最终结果里就混进了无效的空列表。可以用两种方法解决:
方法1:调整JSONPath查询逻辑
先筛选出flags包含inhibitor的entries条目,再提取对应的flags数组:
- name: Set appropriate facts based on the report set_fact: leapp_preupgrade_report_inhibitors: > {{ leapp_preupgrade_report["entries"] | json_query("[?flags.contains(@, 'inhibitor')].flags") }} - debug: msg: "{{ leapp_preupgrade_report_inhibitors }}"
这里[?flags.contains(@, 'inhibitor')]会先过滤符合条件的条目,再通过.flags提取目标数组,不会包含空的flags数组。
方法2:用Ansible原生过滤器组合实现
如果觉得JSONPath不够直观,也可以用Ansible内置过滤器完成:
- name: Set appropriate facts based on the report set_fact: leapp_preupgrade_report_inhibitors: > {{ leapp_preupgrade_report["entries"] | selectattr('flags', 'contains', 'inhibitor') | map(attribute='flags') | list }} - debug: msg: "{{ leapp_preupgrade_report_inhibitors }}"
逻辑说明:
selectattr('flags', 'contains', 'inhibitor'):筛选出flags数组包含inhibitor的条目map(attribute='flags'):提取这些条目中的flags数组list:将结果转换为标准列表格式
两种方法都能得到预期结果,仅返回包含inhibitor的flags数组。
内容的提问来源于stack exchange,提问作者pilipeet
相关产品推荐
相关产品推荐

