Ansible中如何改写YAML变量 让item值按stdout_lines长度重复为数组
Ansible 动态生成重复元素数组实现方案
你可以直接通过Jinja2内置语法实现需求,无需自定义插件,可自动适配stdout_lines的动态长度,兼容Ansible 2.9及以上版本。
核心实现逻辑
遍历原result列表的每一个条目,针对每个条目:
- 读取当前条目的
stdout_lines数组长度 - 生成和该长度一致、所有元素均为原
item值的数组,替换原有字符串类型的item值 - 保留原
stdout_lines字段内容完全不变
可直接复用的Playbook代码
最直观、兼容性最好的写法是直接用Jinja2列表渲染实现:
- name: 转换result变量结构 ansible.builtin.set_fact: new_result: result: >- [ {% for entry in result %} { "item": {{ [entry.item] * entry.stdout_lines | length }}, "stdout_lines": {{ entry.stdout_lines }} }{% if not loop.last %},{% endif %} {% endfor %} ]
注:上面写法加了
loop.last判断,避免最后一个元素后生成多余逗号,严格符合JSON/YAML语法规范。
如果你的场景中item后续可能替换为字典、列表等非基础类型,推荐用product过滤器的写法避免引用复用问题,兼容性同样很好:
- name: 转换result变量结构(兼容复杂item类型) ansible.builtin.set_fact: new_result: result: "{{ [ { 'item': entry.stdout_lines | product([entry.item]) | map('last') | list, 'stdout_lines': entry.stdout_lines } for entry in result ] }}"
效果验证
传入你给出的原始result变量后,生成的new_result.result结构完全匹配预期:
- 第一个条目
stdout_lines长度为5,item字段自动生成长度为5、所有元素为192.168.0.1的数组 - 第二个条目
stdout_lines长度为3,item字段自动生成长度为3、所有元素为192.168.0.2的数组 - 无论
stdout_lines后续长度如何变化,都不需要修改代码,会自动适配长度。
内容的提问来源于stack exchange,提问作者perl
相关产品推荐
相关产品推荐

