3

I need to merge two files without duplicate entries in it. is there any way i can achieve it through ansible modules. Ex i have two files /etc/hosts1 and /etc/hosts2. I need to have one /etc/hosts file with all entries present in both /etc/hosts1 and /etc/hosts2 without duplicate entries. How can i achieve this. An example would be appreciated

- name: Merge two files
  assemble:
    src: /etc/hosts1
    dest: /etc/hosts2

The above assemble module fails

2 Answers2

5

This works. It reads the contents of all files and reduces the resulting array of lines to unique values. Then a new file with those lines is created.

- hosts: localhost
  gather_facts: no
  vars:
    hostsfiles:
      - /tmp/hosts1
      - /tmp/hosts2
  tasks:
  - name: read files
    command: awk 1 {{ hostsfiles | join(' ') }}
    register: hosts_contents
  - name: create hosts file
    copy:
      dest: /tmp/hosts
      content: "{{ hosts_contents.stdout_lines | unique |join('\n') }}"

I'm using awk 1 instead of cat to add potentially missing line breaks to the end of the source files.

Gerald Schneider
  • 26,582
  • 8
  • 65
  • 97
0

Use slurp to get file content, ~ operator to merge and copy to store sorted content.

# lookup('ansible.builtin.file') does only read file on controler, use slurp instead.
- name: Extract files content on remote host 
  ansible.builtin.slurp:
    src: "{{ item }}"
  register: _file_content
  loop:
    - /etc/hosts
    - /etc/resolv.conf
  • name: Decrypt base64, concat, sort and utput to destination file. ansible.builtin.copy: content: "{{ ((_file_content.results.0.content | b64decode) ~ (_file_content.results.1.content | b64decode) ) | split('\n') | sort | unique | join('\n') }}" dest: /tmp/nicely-sorted-file

fraff
  • 119