Reputation: 207
I use lineinfile module to insert a line that doesn't exists but when it's exists with multiple space, it still insert a line.
Input:
one two three
Expect:
(not exists) < Insert
one two three < Don't insert (it's correct)
one two three < Don't insert (having same words but multiple spaces)
My code:
- lineinfile:
path: /somefile
line: 'one two three'
My output:
Before : one two three
After : one two three
one two three
Upvotes: 0
Views: 2951
Reputation: 67959
Q: "Expect"
1. (not exists) < Insert
2. one two three < Don't insert (it's correct)
3. one two three < Don't insert (having same words but multiple spaces)
A: It's not possible to fulfill all the expectations in single run of the module lineinfile
. It's possible to use backrefs and preserve the spacing (case 3.). But new lines won't be inserted (case 1.). Without backrefs
new lines will be added, but the spacing of existing lines won't be preserved (case 2.).
No backrefs
The task below does the job. In particular, regexp
matches any sequences in front, among, and after the words
- lineinfile:
path: test.txt
regexp: '^(.*){{ item.0 }}(.*){{ item.1 }}(.*){{ item.2 }}(.*)$'
line: '{{ item.0 }} {{ item.1 }} {{ item.2 }}'
loop:
- ['one','two','three']
- ['four','five','six']
Given the file test.txt
shell> cat test.txt
one two three
the playbook with this task gives
shell> ansible-playbook pb.yml
shell> cat test.txt
one two three
four five six
As a next example, the regexp
below gives the same result and restricts the sequence to whitespace only. At least one space must be among the words.
- lineinfile:
path: test.txt
regexp: '^(\s*){{ item.0 }}(\s+){{ item.1 }}(\s+){{ item.2 }}(\s*)$'
line: '{{ item.0 }} {{ item.1 }} {{ item.2 }}'
loop:
- ['one','two','three']
- ['four','five','six']
Backrefs
It's possible to preserve the spacing of the existing lines. See backrefs. But, lines that do not exist won't be added.
- lineinfile:
backrefs: true
path: test.txt
regexp: '^(.*){{ item.0 }}(.*){{ item.1 }}(.*){{ item.2 }}(.*)$'
line: '{{ item.0 }}\2{{ item.1 }}\3{{ item.2 }}'
loop:
- ['one','two','three']
- ['four','five','six']
For example, given the same file
shell> cat test.txt
one two three
the playbook with this task skips both iterations and changes nothing
shell> ansible-playbook pb.yml
shell> cat test.txt
one two three
Upvotes: 1