Home > database >  insert files lines into another depending regex filter in Ansible
insert files lines into another depending regex filter in Ansible

Time:08-13

I would copy lines from a file /tmp/test1 to a file /tmp/test2 the /tmp/test1 contains:

  : argument1 : ALL
  : argument2 : ALL
  : @test1 : ALL
  : @test2 : ALL
  : @test3 : ALL

the /tmp/test2 contains:

  : argument1.1 : ALL
  : argument2192 : ALL
  : @example : ALL
  : @test2 : ALL
  : @example1 : ALL

So my main goal is to insert every line that doesn't exist in /tmp/test2 from file /tmp/test1 and that the line added must be added at the end of the last line which is containing the same beginning after : : ^[[:alpha:]] and ^@, so /tmp/test2 should look like this:

  : argument1.1  : ALL
  : argument2192 : ALL
  : argument1 : ALL
  : argument2 : ALL
  : @example : ALL
  : @test2 : ALL
  : @example1 : ALL
  : @test1 : ALL
  : @test3 : ALL

I got a reply about how to merge the 2 files from this answer Vladimir Botka_answer. But what is causing an issue for me is the : : at the begining of each <line>, the filter must be applied after that if it starts with @ or alpha

CodePudding user response:

Put prefix and regex into variables and test the first 5 characters. For example,

    - name: insert line
      lineinfile:
        path: /tmp/test2
        line: "{{ item }}"
        insertafter: "{{ (item[0:5] == prefix)|ternary('EOF', omit) }}"
        insertbefore: "{{ (item[0:5] != prefix)|ternary(regex, omit) }}"
        firstmatch: true
      loop: "{{ tmp_content.stdout_lines }}"
      vars:
        prefix: '  : @'
        regex: '^\  \: @.*$'

gives

shell> cat /tmp/test2
  : argument1.1 : ALL
  : argument2192 : ALL
  : argument1 : ALL
  : argument2 : ALL
  : @example : ALL
  : @test2 : ALL
  : @example1 : ALL
  : @test1 : ALL
  : @test3 : ALL

  • Example of a complete playbook for testing
- hosts: localhost
  tasks:
    - name: check test1 content
      command: cat /tmp/test1
      register: tmp_content
      changed_when: false
    - name: insert line
      lineinfile:
        path: /tmp/test2
        line: "{{ item }}"
        insertafter: "{{ (item[0:5] == prefix)|ternary('EOF', omit) }}"
        insertbefore: "{{ (item[0:5] != prefix)|ternary(regex, omit) }}"
        firstmatch: true
      loop: "{{ tmp_content.stdout_lines }}"
      vars:
        prefix: '  : @'
        regex: '^\  \: @.*$'
  • The playbook is idempotent. See the output of the diff_mode below
shell> ansible-playbook pb.yml --diff
...
TASK [insert line] ****************************************
--- before: /tmp/test2 (content)
    after: /tmp/test2 (content)
@@ -1,5  1,6 @@
   : argument1.1 : ALL
   : argument2192 : ALL
   : argument1 : ALL
   : @example : ALL
   : @test2 : ALL
   : @example1 : ALL

changed: [localhost] => (item=  : argument1 : ALL)
--- before: /tmp/test2 (content)
    after: /tmp/test2 (content)
@@ -1,6  1,7 @@
   : argument1.1 : ALL
   : argument2192 : ALL
   : argument1 : ALL
   : argument2 : ALL
   : @example : ALL
   : @test2 : ALL
   : @example1 : ALL

changed: [localhost] => (item=  : argument2 : ALL)
--- before: /tmp/test2 (content)
    after: /tmp/test2 (content)
@@ -5,3  5,4 @@
   : @example : ALL
   : @test2 : ALL
   : @example1 : ALL
   : @test1 : ALL

changed: [localhost] => (item=  : @test1 : ALL)
ok: [localhost] => (item=  : @test2 : ALL)
--- before: /tmp/test2 (content)
    after: /tmp/test2 (content)
@@ -6,3  6,4 @@
   : @test2 : ALL
   : @example1 : ALL
   : @test1 : ALL
   : @test3 : ALL

changed: [localhost] => (item=  : @test3 : ALL)

Q: " Add the lines containing @ behind the last match line containing @."

A: Use regex both in insertafter and insertbefore, and select firstmatch according the prefix. Technically, append @ lines to the @ block and prepend others. For example, given the file

shell> cat /tmp/test2
  : argument1.1 : ALL
  : argument2192 : ALL
  : @example : ALL
  : @test2 : ALL
  : @example1 : ALL
  : <rubish>

The task below does the job

    - name: insert line
      lineinfile:
        path: /tmp/test2
        line: "{{ item }}"
        insertafter: "{{ (item[0:5] == prefix)|ternary(regex, omit) }}"
        insertbefore: "{{ (item[0:5] != prefix)|ternary(regex, omit) }}"
        firstmatch: "{{ (item[0:5] != prefix)|ternary(true, false) }}"
      loop: "{{ tmp_content.stdout_lines }}"
      vars:
        prefix: '  : @'
        regex: '^\  \: @.*$'

See the output of the diff_mode below

shell> ansible-playbook pb.yml --diff
...
TASK [insert line] ******************************************
--- before: /tmp/test2 (content)
    after: /tmp/test2 (content)
@@ -1,5  1,6 @@
   : argument1.1 : ALL
   : argument2192 : ALL
   : argument1 : ALL
   : @example : ALL
   : @test2 : ALL
   : @example1 : ALL

changed: [localhost] => (item=  : argument1 : ALL)
--- before: /tmp/test2 (content)
    after: /tmp/test2 (content)
@@ -1,6  1,7 @@
   : argument1.1 : ALL
   : argument2192 : ALL
   : argument1 : ALL
   : argument2 : ALL
   : @example : ALL
   : @test2 : ALL
   : @example1 : ALL

changed: [localhost] => (item=  : argument2 : ALL)
--- before: /tmp/test2 (content)
    after: /tmp/test2 (content)
@@ -5,4  5,5 @@
   : @example : ALL
   : @test2 : ALL
   : @example1 : ALL
   : @test1 : ALL
   : <rubish>

changed: [localhost] => (item=  : @test1 : ALL)
ok: [localhost] => (item=  : @test2 : ALL)
--- before: /tmp/test2 (content)
    after: /tmp/test2 (content)
@@ -6,4  6,5 @@
   : @test2 : ALL
   : @example1 : ALL
   : @test1 : ALL
   : @test3 : ALL
   : <rubish>

changed: [localhost] => (item=  : @test3 : ALL)
  • Related