Is selectattr
过滤器期望列表中的所有字典都具有相同的键?
更准确地说,它期望列表中的所有字典都具有您正在选择的属性。如果列表中并非所有字典都有它,您必须首先过滤掉未定义的项目。这可以通过以下方式完成selectattr
以及。 (感谢@Randy 自我最初的回答以来使这一点变得更加清晰)。
在您的情况下,json_query filter https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#selecting-json-data-json-queries(它实现了jmespath http://jmespath.org/)有时也可以以更紧凑的方式完成这项工作。但它不是核心过滤器,需要具有community.general收藏 https://docs.ansible.com/ansible/latest/collections/community/general/安装。
以下是从您的上述要求中摘取的一些示例,使用核心过滤器和json_query
解决方案。
剧本:
---
- name: "Filter data with core filters or json query"
hosts: "localhost"
gather_facts: false
vars:
# Your initial data on a single line for legibility
test_var: [{"vm":"vm1","ip":"10.10.10.1"},{"vm":"vm2","ip":"10.10.10.2"},{"test_vm":"something","process_1":"X","process_2":"Y","process_3":"Z"},{"another_vm":"something_other"}]
tasks:
- name: Get objects having vm==vm1
vars:
msg: |-
With core filters: {{ test_var | selectattr('vm', 'defined') | selectattr('vm', '==', 'vm1') | list }}
With json_query: {{ test_var | json_query("[?vm=='vm1']") | list }}
debug:
msg: "{{ msg.split('\n') }}"
- name: Get all objects having vm attribute
vars:
msg: |-
With core filters: {{ test_var | selectattr('vm', 'defined') | list }}
With json_query: {{ test_var | json_query("[?vm]") | list }}
debug:
msg: "{{ msg.split('\n') }}"
- name: Get all objects having process_2 attribute
vars:
msg: |-
With core filters: {{ test_var | selectattr('process_2', 'defined') | list }}
With json_query: {{ test_var | json_query("[?process_2]") | list }}
debug:
msg: "{{ msg.split('\n') }}"
- name: Get only a list of process_2 attributes
vars:
msg: |-
With core filters: {{ test_var | selectattr('process_2', 'defined') | map(attribute='process_2') | list }}
With json_query: {{ test_var | json_query("[].process_2") | list }}
debug:
msg: "{{ msg.split('\n') }}"
这使:
PLAY [Filter data with core filters or json query] *********************************************************************
TASK [Get objects having vm==vm1] *********************************************************************
ok: [localhost] => {
"msg": [
"With core filters: [{'vm': 'vm1', 'ip': '10.10.10.1'}]",
"With json_query: [{'vm': 'vm1', 'ip': '10.10.10.1'}]"
]
}
TASK [Get all objects having vm attribute] *********************************************************************
ok: [localhost] => {
"msg": [
"With core filters: [{'vm': 'vm1', 'ip': '10.10.10.1'}, {'vm': 'vm2', 'ip': '10.10.10.2'}]",
"With json_query: [{'vm': 'vm1', 'ip': '10.10.10.1'}, {'vm': 'vm2', 'ip': '10.10.10.2'}]"
]
}
TASK [Get all objects having process_2 attribute] *********************************************************************
ok: [localhost] => {
"msg": [
"With core filters: [{'test_vm': 'something', 'process_1': 'X', 'process_2': 'Y', 'process_3': 'Z'}]",
"With json_query: [{'test_vm': 'something', 'process_1': 'X', 'process_2': 'Y', 'process_3': 'Z'}]"
]
}
TASK [Get only a list of process_2 attributes] *********************************************************************
ok: [localhost] => {
"msg": [
"With core filters: ['Y']",
"With json_query: ['Y']"
]
}
PLAY RECAP *********************************************************************
localhost : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0