下面是我的数据的一个人为示例。当列表中的任何字典mylst.env具有带有名称的键时,我想提取所有客户的姓名n1
我想这可以通过嵌套循环来完成,但无法弄清楚如何实现。
- hosts: localhost
gather_facts: no
vars:
- mylst:
- apiVersion: v1
name: customer1
metaData:
cycles: 10
ships: 12
env:
- name: n1
value: v1
- name: n2
value: v2
- apiVersion: v1
name: customer2
metaData:
cycles: 10
ships: 12
env:
- name: n1
value: v1
- name: n3
value: v3
- apiVersion: v1
name: customer3
metaData:
cycles: 10
ships: 12
env:
- name: n3
value: v1
- name: n4
value: v4
tasks:
- set_fact:
cust_lst: "{{ cust_lst|default([]) + [item.name] }}"
with_items: "{{ mylst }}"
# loop through item.env and look for elements where elem.name == n1
when: item.env | length > 0
- debug: var=cust_lst
Run Code Online (Sandbox Code Playgroud)
Mat*_*t P 10
过滤json_query器是完成此类任务的绝佳工具。你需要花一点时间来理解,但请尝试一下:
- set_fact:
cust_lst: "{{ mylst | json_query(query) }}"
vars:
query: "[?env[?name=='n1']].name"
Run Code Online (Sandbox Code Playgroud)
您可以使用列表map上的过滤器item.env来获取每个元素包含的名称列表mylst。然后,如果关键字“n1”在该列表中,则添加到final_var. 请看下面
---
- hosts: localhost
gather_facts: false
vars:
mylst:
- apiVersion: v1
name: customer1
metaData:
cycles: 10
ships: 12
env:
- name: n1
value: v1
- name: n2
value: v2
- apiVersion: v1
name: customer2
metaData:
cycles: 10
ships: 12
env:
- name: n1
value: v1
- name: n3
value: v3
- apiVersion: v1
name: customer3
metaData:
cycles: 10
ships: 12
env:
- name: n3
value: v1
- name: n4
value: v4
- apiVersion: v1
name: customer4
metaData:
cycles: 10
ships: 12
env:
- name2: n3
value: v1
- name2: n4
value: v4
tasks:
- name: prepare var
set_fact:
final_var: "{{ final_var | default([]) + [item.name] }}"
when: '"n1" in {{ item.env | selectattr("name", "defined") | map(attribute="name") | list }}'
with_items:
- "{{ mylst }}"
- name: print var
debug:
var: final_var
Run Code Online (Sandbox Code Playgroud)
您会注意到我在 中添加了第四个元素,其中mylst不包含 key =“name”的属性。这些将被过滤器过滤掉selectattr("name", "defined",然后传递给地图过滤器。
PLAY [localhost] *******************************************************************************************************************************************************************************************************
TASK [prepare var] *****************************************************************************************************************************************************************************************************
[WARNING]: conditional statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: "n1" in {{ item.env | selectattr("name", "defined") | map(attribute="name") | list }}
ok: [localhost] => (item={'apiVersion': 'v1', 'name': 'customer1', 'metaData': {'cycles': 10, 'ships': 12}, 'env': [{'name': 'n1', 'value': 'v1'}, {'name': 'n2', 'value': 'v2'}]})
ok: [localhost] => (item={'apiVersion': 'v1', 'name': 'customer2', 'metaData': {'cycles': 10, 'ships': 12}, 'env': [{'name': 'n1', 'value': 'v1'}, {'name': 'n3', 'value': 'v3'}]})
skipping: [localhost] => (item={'apiVersion': 'v1', 'name': 'customer3', 'metaData': {'cycles': 10, 'ships': 12}, 'env': [{'name': 'n3', 'value': 'v1'}, {'name': 'n4', 'value': 'v4'}]})
skipping: [localhost] => (item={'apiVersion': 'v1', 'name': 'customer4', 'metaData': {'cycles': 10, 'ships': 12}, 'env': [{'name2': 'n3', 'value': 'v1'}, {'name2': 'n4', 'value': 'v4'}]})
TASK [print var] *******************************************************************************************************************************************************************************************************
ok: [localhost] => {
"final_var": [
"customer1",
"customer2"
]
}
PLAY RECAP *************************************************************************************************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Run Code Online (Sandbox Code Playgroud)
希望这些有帮助。
该任务被发现规避了 2.7.5 错误:
- name: prepare var
set_fact:
final_var: "{{ final_var | default([]) + [item.name] }}"
when: "'n1' in item.env | selectattr('name', 'defined') | map(attribute='name') | list"
with_items:
- "{{ mylst }}"
Run Code Online (Sandbox Code Playgroud)