1

I want to append attribute to a file, instead of replacing or setting it on a new line.

Content of file:

PATH = "/a/path"

The variable which attributes has to append in the file:

"{{ key.values() | map(attribute='hi') | list | join(' ') }}"

The output of the variable is:

/hi1 /hi2 /hi3 

Trying to append with lineinfile, but the parameter insertafter places the attributes on a new line, instead of the same line.

- lineinfile:
    dest: /file
    state: present
    insertafter: 'PATH = "'
    line: "{{ mounts.values() | map(attribute='mountpoint') | list | join(' ') }}"

Expected result:

PATH = "/a/path /hi1 /h2 /hi3"

Actual result:

PATH = "/a/path"
/hi1 /hi2 /hi3

Receiving syntax errors if I use the method described here: Ansible: insert a single word on an existing line in a file

Which module should I use for this particular use case?

Using Ansible v2.1.2.0


edit

The backrefs option gives the same result, which is not expected:

 - lineinfile:
     dest: /file
     backrefs: yes
     regexp: 'PATH = "'
     line: "{{ key.values() | map(attribute='hi') | list | join(' ') }}"
Community
  • 1
  • 1
Kevin C
  • 4,851
  • 8
  • 30
  • 64
  • When you use backrefs your regex has to have capturing groups for it to work. See my example below. – Mir Nov 24 '16 at 13:41

2 Answers2

2

Thanks for helping @Mir. Final solution:

 - lineinfile:
    dest: /file
    backrefs: yes
    regexp: '(^PATH\s+\=\s+)(?:")([\w+\s/]+)(?<!{{ hi }})(?:")'
    line: '\1"\2 {{ hi }}"'

Where hi is the variable.

techraf
  • 64,883
  • 27
  • 193
  • 198
Kevin C
  • 4,851
  • 8
  • 30
  • 64
0

Lineinfile module has the backrefs option that goes in pair with the regexp option and allows you to match an existing line and change only parts of it.

Something like (not tested)

- lineinfile:
  [...]
  regexp: ^PATH = "(.*)"$
  line: PATH="\1 {{ your_variable_here}}"
  backrefs: yes

Is probably what you need.

Mir
  • 1,575
  • 1
  • 18
  • 31
  • Got the same result. Because "If the regexp does match, the last matching line will be replaced by the expanded line parameter." It replaces the whole line. – Kevin C Nov 24 '16 at 12:41
  • @Kevin it replaces the line, but you can use backreferences to keep in your line parts (or all) of the existing line, so it can be used to add parts to an existing string. – Mir Nov 24 '16 at 13:30