loops - Ansible - 迭代两个列表但使用第一个列表的索引

标签 loops ansible

我试图通过使用第一个列表的索引来循环两个列表。这是我使用 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/

相关文章:

ansible - 将文件的行转换为项目列表

将变量内容复制到事实中后,Ansible 会抛出错误

c - while 循环,从 scanf 读取 int 与 char,true 和 false

php - 从 mysql 表中检索数据时循环显示相同的图像

matlab - 遍历文件夹?

wordpress - 使 `get_url` 和 `unarchive` ansible 命令幂等

php - Ansible mysql_user 模块不接受加密密码

函数中的 Ansible 更新变量

python - 如何在 Python 中迭代两个或多个列表项的元组?

python - for循环迭代之间的延迟(python)