I would copy lines from a file /tmp/test1
to a file /tmp/test2
the /tmp/test1
contains:
argument1
argument2
@test1
@test2
@test3
the /tmp/test2
contains:
argument1.1
argument2192
@example
@test2
@example1
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 begin of line: ^[[:alpha:]]
and ^@
, so /tmp/test2
should look like this:
argument1.1
argument2192
argument1
argument2
@example
@test2
@example1
@test1
@test3
I created this playbook but it doesn't do what i am looking for:
- name: check test1 content
command: cat /tmp/test1
register: tmp_content
- name: insert line
lineinfile:
path: /tmp/test2
line: '{{item}}'
insertafter: "^@*"
loop: "{{tmp_content.stdout_lines}}"
CodePudding user response:
1) "Insert every line that doesn't exist in /tmp/test2 from file /tmp/test1"
2) "The line added must be added at the end of the last line which is containing the same beginning."
A: The task below does the job. If the first character is @
the line is inserted at the end of the file. Otherwise, the line is inserted before the first line starting with @
. The parameters insertafter and insertbefore may not be used together. The negative options omit make the parameters insertafter and insertbefore mutually exclusive
- name: insert line
lineinfile:
path: /tmp/test2
line: "{{ item }}"
insertafter: "{{ (item.0 == '@')|ternary('EOF', omit) }}"
insertbefore: "{{ (item.0 != '@')|ternary('^@.*$', omit) }}"
firstmatch: true
loop: "{{ tmp_content.stdout_lines }}"
Notes
- Example of a complete playbook for testing
shell> cat pb.yml
- 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 == '@')|ternary('EOF', omit) }}"
insertbefore: "{{ (item.0 != '@')|ternary('^@.*$', omit)}}"
firstmatch: true
loop: "{{ tmp_content.stdout_lines }}"
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
argument2192
argument1
@example
@test2
@example1
changed: [localhost] => (item=argument1)
--- before: /tmp/test2 (content)
after: /tmp/test2 (content)
@@ -1,6 1,7 @@
argument1.1
argument2192
argument1
argument2
@example
@test2
@example1
changed: [localhost] => (item=argument2)
--- before: /tmp/test2 (content)
after: /tmp/test2 (content)
@@ -5,3 5,4 @@
@example
@test2
@example1
@test1
changed: [localhost] => (item=@test1)
ok: [localhost] => (item=@test2)
--- before: /tmp/test2 (content)
after: /tmp/test2 (content)
@@ -6,3 6,4 @@
@test2
@example1
@test1
@test3
changed: [localhost] => (item=@test3)
- Brute force option
Read the files
- command: cat /tmp/test1
register: test1
- command: cat /tmp/test2
register: test2
Declare the variables
l1_alpha: "{{ test1.stdout_lines|select('match', '^[^@].*$') }}"
l1_glyph: "{{ test1.stdout_lines|select('match', '^@.*$') }}"
l2_alpha: "{{ test2.stdout_lines|select('match', '^[^@].*$') }}"
l2_glyph: "{{ test2.stdout_lines|select('match', '^@.*$') }}"
l1_alpha_diff: "{{ l1_alpha|difference(l2_alpha) }}"
l1_glyph_diff: "{{ l1_glyph|difference(l2_glyph) }}"
result: "{{ l2_alpha l1_alpha_diff l2_glyph l1_glyph_diff }}"
This gives the expected result
- debug:
msg: |
{% for line in result %}
{{ line }}
{% endfor %}
msg: |-
argument1.1
argument2192
argument1
argument2
@example
@test2
@example1
@test1
@test3
Write it to a file
- copy:
dest: /tmp/test2
content: |
{% for line in result %}
{{ line }}
{% endfor %}
gives
shell> cat /tmp/test2
argument1.1
argument2192
argument1
argument2
@example
@test2
@example1
@test1
@test3
Example of a complete playbook for testing
shell> cat pb.yml
- hosts: localhost
vars:
l1_alpha: "{{ test1.stdout_lines|select('match', '^[^@].*$') }}"
l1_glyph: "{{ test1.stdout_lines|select('match', '^@.*$') }}"
l2_alpha: "{{ test2.stdout_lines|select('match', '^[^@].*$') }}"
l2_glyph: "{{ test2.stdout_lines|select('match', '^@.*$') }}"
l1_alpha_diff: "{{ l1_alpha|difference(l2_alpha) }}"
l1_glyph_diff: "{{ l1_glyph|difference(l2_glyph) }}"
result: "{{ l2_alpha l1_alpha_diff l2_glyph l1_glyph_diff }}"
tasks:
- command: cat /tmp/test1
register: test1
changed_when: false
- command: cat /tmp/test2
register: test2
changed_when: false
- copy:
dest: /tmp/test2
content: |
{% for line in result %}
{{ line }}
{% endfor %}
The playbook is idempotent.