简体   繁体   English

如何比较 Ansible 中的多个文件

[英]How to compare multiple files in Ansible

I am trying to find a way to compare multiple files in a directory to files in another directory.我正在尝试找到一种方法来将目录中的多个文件与另一个目录中的文件进行比较。 For example - there are 10 files in a directory /home/ansible/properties/ and similar set of files in another directory on remote host like /opt/apps/properties/.例如 - 目录 /home/ansible/properties/ 中有 10 个文件,远程主机上的另一个目录(如 /opt/apps/properties/)中有类似的文件集。 I want to compare each of them probably using checksum and even if one of the file is changed then do some task -我想比较它们中的每一个,可能使用校验和,即使其中一个文件被更改,然后做一些任务 -

Below of my play can compare one file but is there a way to compare all the files or for that matter a directory?我的剧本下面可以比较一个文件,但是有没有办法比较所有文件或目录?

- name: Get checksum of my First file
  stat:
    path : "/home/ansible/properties/my.properties"
  register: myfirstfile

- name: Current SHA1
  set_fact:
    1stFilechecksum: "{{ myfirstfile.stat.checksum }}"

- name: Get checksum of my Second File
  stat:
    path : "/opt/aaps/properties/my.properties"
  register: mysecondfile

- name: Current SHA1
  set_fact:
    2ndFilechecksum: "{{ mysecondfile.stat.checksum }}"

- name: Comparing 2 files
  debug:
    msg: "Do Something....."
  when:  1stFilechecksum != 2ndFilechecksum

Test file tree according to your description根据您的描述测试文件树

... or at least what I understood from it. ……或者至少我从中了解到的。

/tmp/test/a          /tmp/test/b
├── file10.txt       ├── file10.txt
├── file1.txt        ├── file1.txt
├── file2.txt        ├── file2.txt
├── file3.txt        ├── file3.txt
├── file4.txt        ├── file4.txt
├── file5.txt        ├── file5.txt
├── file6.txt        ├── file6.txt
├── file7.txt        ├── file7.txt
├── file8.txt        ├── file8.txt
├── file9.txt        ├── file9.txt
└── toto.txt         └── titi.txt

As you can see all files are common except on file in each dir.如您所见,所有文件都是通用的,除了每个目录中的文件。 Those will be be excluded from comparison.这些将被排除在比较之外。 For the common files all are different except file2.txt and file5.txt having the same content.对于通用文件,除了file2.txtfile5.txt具有相同的内容外,其他文件都是不同的。

The bases used for the solution用于解决方案的碱基

  • We search for all files in both directories in a loop with find .我们使用find循环搜索两个目录中的所有文件。 All files in a are in results[0] , those from b in results[1] . a中的所有文件都在results[0]中, b中的所有文件都在results[1]中。 The get_checksum option gathers the info we need. get_checksum选项收集我们需要的信息。
  • In the next task:在下一个任务中:
    • We loop on files found in a .我们循环a .
    • On each iteration, we calculate the corresponding file in b by selecting with selectattr only the list elements having the same path name after replacing the dir path.在每次迭代中,我们通过在替换 dir 路径后使用selectattr仅选择具有相同path名的列表元素来计算b中的相应文件。 Keeping the first element of the result gives our file.保留结果的第一个元素给出了我们的文件。 In case the result is empty (not a file in common), we default to an empty object如果结果为空(不是公共文件),我们默认为空 object
    • The when clause checks that the files exist (common else we skip) and that they are different (checksum is not equal) when 子句检查文件是否存在(常见的我们跳过)以及它们是否不同(校验和不相等)
    • loop_control is used to customize the loop varialbe name for readability (ie item => file1) and to limit the output of the loop item to something understandable. loop_control用于自定义循环变量名称以提高可读性(即 item => file1)并将循环项目的 output 限制为可以理解的内容。

The playbook剧本

---
- name: compare files in two dirs
  hosts: localhost
  gather_facts: false

  vars:
    dir1: /tmp/test/a
    dir2: /tmp/test/b

  tasks:

    - name: "Find all files in {{ dir1 }} and {{ dir2 }}"
      find:
        paths:
          - "{{ item }}"
        get_checksum: true
      register: search_files
      loop:
        - "{{ dir1 }}"
        - "{{ dir2 }}"


    - name: "Compare checksums from {{ dir1 }} to {{ dir2 }}. do something if different"
      vars:
        file2: >-
          {{
            search_files.results[1].files |
            selectattr('path', 'eq', file1.path | replace(dir1, dir2)) |
            list |
            first |
            default({})
          }}
      debug:
        msg: "Files differ. Do something"
      loop: "{{ search_files.results[0].files }}"
      loop_control:
        loop_var: file1
        label: "Comparing {{ file1.path }} to {{ file2.path | default('N/A') }}"
      when:
        - file2.path is defined
        - file1.checksum != file2.checksum

The result结果

$ ansible-playbook test.yml 

PLAY [compare files in two dirs] ***************************************************************************************************************

TASK [Find all files in /tmp/test/a and /tmp/test/b] *******************************************************************************************
ok: [localhost] => (item=/tmp/test/a)
ok: [localhost] => (item=/tmp/test/b)

TASK [Compare checksums from /tmp/test/a to /tmp/test/b. do something if different] ************************************************************
ok: [localhost] => (item=Comparing /tmp/test/a/file1.txt to /tmp/test/b/file1.txt) => {
    "msg": "Files differ. Do something"
}
skipping: [localhost] => (item=Comparing /tmp/test/a/file2.txt to /tmp/test/b/file2.txt) 
ok: [localhost] => (item=Comparing /tmp/test/a/file3.txt to /tmp/test/b/file3.txt) => {
    "msg": "Files differ. Do something"
}
ok: [localhost] => (item=Comparing /tmp/test/a/file4.txt to /tmp/test/b/file4.txt) => {
    "msg": "Files differ. Do something"
}
skipping: [localhost] => (item=Comparing /tmp/test/a/file5.txt to /tmp/test/b/file5.txt) 
ok: [localhost] => (item=Comparing /tmp/test/a/file6.txt to /tmp/test/b/file6.txt) => {
    "msg": "Files differ. Do something"
}
ok: [localhost] => (item=Comparing /tmp/test/a/file7.txt to /tmp/test/b/file7.txt) => {
    "msg": "Files differ. Do something"
}
ok: [localhost] => (item=Comparing /tmp/test/a/file8.txt to /tmp/test/b/file8.txt) => {
    "msg": "Files differ. Do something"
}
ok: [localhost] => (item=Comparing /tmp/test/a/file9.txt to /tmp/test/b/file9.txt) => {
    "msg": "Files differ. Do something"
}
ok: [localhost] => (item=Comparing /tmp/test/a/file10.txt to /tmp/test/b/file10.txt) => {
    "msg": "Files differ. Do something"
}
skipping: [localhost] => (item=Comparing /tmp/test/a/toto.txt to N/A) 

PLAY RECAP *************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM