我试图通过使用第一个列表的索引来循环两个列表。这是我使用 python 编写的代码(我会先在 python 中尝试,然后再在 Ansible 中实现)
a = ['host1', 'host2']
b = [[1,2,3],[4,5,6,7]]
for idx, i in enumerate(a):
for j in b[idx]:
print(i,j)
这是输出
host1 1
host1 2
host1 3
host2 4
host2 5
host2 6
host2 7
我尝试在 Ansible 中应用同样的东西,但我无法弄清楚。我已经通过压缩两者并将它们转换为字典并使用 dictvar|dict2items|subelements('value')
解决了这个问题。但我想知道是否可以像在 python 中解决它一样来实现它。
这是我当前在 Ansible 中的实现:
- name: KeyValue
hosts: all
serial: 1
tasks:
- name: Print all
set_fact:
hostnames: ['host1', 'host2', 'host3']
ports: [[1,2,3,4],[5,6,7], [8,9,10]]
- name: print vars
debug:
msg: "{{ hostnames }} and {{ ports }}"
- name: joining host and port as dict
set_fact:
hostandport: "{{ dict(hostnames | zip(ports)) }}"
- name: Print the key and value
debug:
msg: "key is {{ item.0.key }} and value is {{ item.1 }}"
loop: "{{ hostandport | dict2items | subelements('value')}}"
最佳答案
Jinja做你想做的事。例如,
hostandport: |
{% for host,ports in a|zip(b) %}
{% for port in ports %}
{{ host }} {{ port }}
{% endfor %}
{% endfor %}
给出
hostandport: |-
host1 1
host1 2
host1 3
host2 4
host2 5
host2 6
host2 7
注释:
- 用于测试的完整剧本示例
- hosts: localhost
vars:
a: ['host1', 'host2']
b: [[1,2,3],[4,5,6,7]]
hostandport: |
{% for host,ports in a|zip(b) %}
{% for port in ports %}
{{ host }} {{ port }}
{% endfor %}
{% endfor %}
tasks:
- debug:
var: hostandport
- 如果要迭代主机和端口,请拆分行和项目。例如,
- debug:
msg: "Wait for port: {{ item.1 }} at host: {{ item.0 }}"
loop: "{{ hostandport.splitlines()|map('split')|list }}"
给出(删节)
msg: 'Wait for port: 1 at host: host1'
msg: 'Wait for port: 2 at host: host1'
msg: 'Wait for port: 3 at host: host1'
msg: 'Wait for port: 4 at host: host2'
msg: 'Wait for port: 5 at host: host2'
msg: 'Wait for port: 6 at host: host2'
msg: 'Wait for port: 7 at host: host2'
- 如果您想稍后使用它,请在 vars 中声明该列表。例如,下面的剧本给出了相同的结果
- hosts: localhost
vars:
a: ['host1', 'host2']
b: [[1,2,3],[4,5,6,7]]
hostandport: |
{% for host,ports in a|zip(b) %}
{% for port in ports %}
{{ host }} {{ port }}
{% endfor %}
{% endfor %}
hostandport_list: "{{ hostandport.splitlines()|map('split')|list }}"
tasks:
- debug:
msg: "Wait for port: {{ item.1 }} at host: {{ item.0 }}"
loop: "{{ hostandport_list }}"
- 如果要迭代列表,最直接的方法是从头开始创建列表。例如,下面的声明
hostandport: |
{% for host,ports in a|zip(b) %}
{% for port in ports %}
- [{{ host }}, {{ port }}]
{% endfor %}
{% endfor %}
hostandport_list: "{{ hostandport|from_yaml }}"
给予
hostandport_list:
- [host1, 1]
- [host1, 2]
- [host1, 3]
- [host2, 4]
- [host2, 5]
- [host2, 6]
- [host2, 7]
关于loops - Ansible - 迭代两个列表但使用第一个列表的索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73787910/