如何高效循环并合并Lookup/CSV文件字段生成指定格式列表?
问题描述
我需要循环遍历Lookup读取的CSV文件字段,将符合条件的内容合并为指定格式的列表。
示例数据
CSV文件内容
id,hostname,host_ip,country_code,country_name ID01,myhost1,10.2.3.2,US,United States ID02,myhost2,10.2.3.3,US,United States ID03,myhost3,10.2.3.4,UK,United Kingdom ID04,myhost3,10.2.3.4,US,United Kingdom
读取后的列表(hosts_list)
CSV读取后得到的列表结构为hosts_list.list,每个元素是包含对应字段的字典。
预期输出
['US-myhost1', 'US-myhost2', 'US-myhost3']
已尝试的两种方法
方法1 - 循环列表(小数据集适用,大数据效率低)
- name: "Read as a list" set_fact: my_clubbed_list: "{{ my_clubbed_list|default([])+ [ my_clubbed_field ]}}" loop: "{{ hosts_list.list }}" vars: - my_clubbed_field: "{{item.country_code}}-{{item.hostname}}" when: item.country_code == 'US'
方法2 - Jinja循环(速度较快,但写法不够简洁)
- debug: msg: '{{ clubbed }}' vars: clubbed: | " {%- for result in hosts_list.list -%} {% if 'US' == result.country_code %} '{{ result.country_code }}-{{ result.hostname }}', {% endif %} {% endfor %} "
请问有没有更高效简洁的实现方式?
高效实现方案
推荐使用Ansible原生过滤器组合或者json_query,这两种方式基于优化后的Python底层实现,处理大数据集的速度远优于循环set_fact,同时写法简洁易读。
方案1:selectattr + map 过滤器组合
先筛选符合条件的条目,再格式化字段,逻辑直观清晰:
- name: Generate formatted list efficiently set_fact: my_clubbed_list: >- {{ hosts_list.list | selectattr('country_code', 'equalto', 'US') | map('extract', ['country_code', 'hostname']) | map('join', '-') | list }}
方案2:json_query 结构化查询
基于JMESPath语法,适合处理结构化数据,写法极为简洁:
- name: Generate formatted list with json_query set_fact: my_clubbed_list: >- {{ hosts_list.list | json_query("[?country_code=='US'].join('-', [country_code, hostname])") }}
方案优势
- 效率高:原生过滤器和
json_query都是底层优化过的实现,处理大数据集时比循环set_fact快数倍 - 写法简洁:一行代码完成筛选、格式化、转列表的全流程
- 可读性强:逻辑清晰,无需复杂的循环或模板语法
内容的提问来源于stack exchange,提问作者diaryfolio
相关产品推荐
相关产品推荐

