Ansible中如何正确保存find模块结果并解决rsl2遍历报错问题
问题原因
当你用loop注册变量时,rsl2的结构和单次find注册的rsl完全不同:rsl2是一个包含results数组的对象,数组里的每一项对应一次循环迭代的find执行结果,只有每个结果项里才包含files字段。直接访问rsl2.files自然会报错,手动收集结果还会出现嵌套数组的问题。
解决方案
有两种实用的处理方式:
方式一:合并两次Find操作(更简洁高效)
其实可以直接通过路径匹配完成需求,不用分两次查询:
- name: "定位所有目标文件" find: paths: "/some_dir/*some_patterns*/dir2" patterns: "*.file" register: target_files - name: "替换文件中的指定单词" replace: dest: "{{ item.path }}" regexp: 'word' replace: 'new_word' loop: "{{ target_files.files }}"
直接用路径模板/some_dir/*some_patterns*/dir2指定查询根路径,配合*.file的文件名匹配,一次find就能拿到所有需要处理的文件。
方式二:修复原有两次Loop逻辑
如果必须保留两次查询的结构,需要从rsl2.results里提取所有files并展平成一维数组:
- name: "find folder with some_patterns in some_dir" find: paths: /some_dir patterns: "*some_patterns*" file_type: "directory" register: rsl - name: "find folder with some_patterns2 in dir2" find: paths: "{{ item.path }}/dir2" patterns: "*.file" register: rsl2 loop: "{{ rsl.files }}" - name: "replace word" replace: dest: "{{ item.path }}" regexp: 'word' replace: 'new_word' # 提取每个循环结果中的files数组,再展平为一维数组 loop: "{{ rsl2.results | map(attribute='files') | flatten }}"
这里用map(attribute='files')从每个results元素中取出对应的文件列表,再通过flatten过滤器把嵌套的数组结构转换成一维数组,这样loop就能正确遍历每一个目标文件。
内容的提问来源于stack exchange,提问作者Sergey Botsman
相关产品推荐
相关产品推荐

