如何在Ansible任务中实现双层循环迭代?
解决Ansible双层迭代删除文件的问题
你的问题核心在于没有正确处理with_items注册后的结果结构,且混用with_items和loop_control导致变量逻辑混乱。以下是修正后的实现方案:
步骤1:筛选目标项并获取待删除文件列表
先遍历versions,仅对name为registryInternet的项执行find命令,并注册结果:
- name: 获取registryInternet对应的待删除文件列表 find: path: "{{ myPath }}/data" excludes: '*int.yml*,*int-prod.yml*' register: files_to_delete loop: "{{ versions }}" when: item.name == 'registryInternet'
这里files_to_delete.results会包含所有符合条件的执行结果:被跳过的项会标记skipped: true,成功执行的项会包含files字段(即找到的文件列表)。
步骤2:遍历待删除文件并执行删除
通过过滤和扁平化处理files_to_delete.results,直接遍历所有需要删除的文件:
- name: 删除所有目标文件 file: path: "{{ file_item.path }}" state: absent loop: "{{ files_to_delete.results | selectattr('skipped', 'undefined') | map(attribute='files') | flatten }}" loop_control: loop_var: file_item
逻辑解释:
selectattr('skipped', 'undefined'):过滤掉被跳过的任务结果(即不符合registryInternet条件的项)map(attribute='files'):提取每个有效结果中的文件列表flatten:将多个文件列表合并为一个扁平列表,确保loop能遍历到每一个文件
替代方案:嵌套循环(若需关联versions项的其他属性)
如果myPath需要和versions的项关联(比如{{ item.path }}/data),可以用嵌套循环的方式,更清晰地关联每个version项和对应的文件:
- name: 遍历registryInternet项并删除对应文件 file: path: "{{ file.path }}" state: absent loop: "{{ versions | selectattr('name', 'equalto', 'registryInternet') | list }}" loop_control: loop_var: version_item with_items: "{{ lookup('ansible.builtin.find', path='{{ myPath }}/data', excludes='*int.yml*,*int-prod.yml*').files }}" loop_control: loop_var: file
内容的提问来源于stack exchange,提问作者Broshet
相关产品推荐
相关产品推荐

