首页 > 解决方案 > 循环查找文件并删除它们

问题描述

我想删除某些包含特定格式的子目录中的文件。但是,我收到了错误

“dict object”没有属性“files”。

下面是我的代码。文件模式将是file_name.file_extension.processID.YYYY-MM-DD@HH:MM:SS~

我的变量

fileToFindInAllSubDirecotry
  - "home/usr/file1"
  - "home/usr/file2"
  - "home/usr/file3/file4"
  - "home/usr/file5"

我的剧本角色

- name: Find file
  find:
    paths: "{{ item }}"
    use_regex: yes
    patterns:
      - '.*\.\d+\.\d{4}-\d{2}-\d{2}@\d{2}:\d{2}:\d{2}~$'
    age: 1d
    recurse: yes
  register: fileToDelete
  loop: "{{ fileToFindInAllSubDirecotry }}"
  
- name: Delete file
  file:
    path: "{{ item.path }}"
    state: absent
  loop: "{{ fileToDelete.files }}"

这是示例文件和目录

home
   |-------usr
             |-------file1
                         |-------configFile.xml
             |-------file2
                         |-------propertiesFile.txt.2012.2020-07-13@23:08:10~
             |-------file3
                         |-------file4
                                     |-------content.yml.2012.2020-04-04@23:08:10~                       
             |-------file5
                         |-------configFile.xml.2012.2020-03-05@13:08:10~

标签: ansible

解决方案


发生这种情况是因为您正在find使用循环填充 ,因此您最终得到的结果将是具有列表的字典或results.

就像是:

ok: [localhost] => {
    "msg": {
        "changed": false,
        "msg": "All items completed",
        "results": [
            {
                ...
                "files": [ ... ],
                ...
                "item": "/home/usr/file1",
                ...
            },
            {
                ...
                "files": [ ... ],
                ...
                "item": "/home/usr/file2",
                ...
            },
            ...
        ]
    }
}

有两种方法可以解决此问题:

  1. 最好的一个,因为正如文档所指出的那样,paths模块 find 的参数可以接受路径列表,只需将整个fileToFindInAllSubDirecotry变量传递给它而不是使用循环,这样您的删除就可以按原样进行:

    - name: Find file
      find:
        paths: "{{ fileToFindInAllSubDirecotry }}"
        use_regex: yes
        patterns:
          - '.*\.\d+\.\d{4}-\d{2}-\d{2}@\d{2}:\d{2}:\d{2}~$'
        age: 1d
        recurse: yes
      register: fileToDelete
    
    - name: Delete file
      file:
        path: "{{ item.path }}"
        state: absent
      loop: "{{ fileToDelete.files }}"
    
  2. 用于json_query获取result[*].files列表flatten的结果列表

    - name: Find file
      find:
        paths: "{{ item }}"
        use_regex: yes
        patterns:
          - '.*\.\d+\.\d{4}-\d{2}-\d{2}@\d{2}:\d{2}:\d{2}~$'
        age: 1d
        recurse: yes
      register: fileToDelete
      loop: "{{ fileToFindInAllSubDirecotry }}"
    
    - name: Delete file
      file:
        path: "{{ item.path }}"
        state: absent
      loop: "{{ fileToDelete | json_query('results[*].files') | flatten }}"
    

推荐阅读