# question on lineinfile module

**URL:** <https://forum.ansible.com/t/question-on-lineinfile-module/21884>\
**Category:** Ansible Project\
**Created:** [June 29, 2016, 6:07am UTC](https://forum.ansible.com/t/question-on-lineinfile-module/21884 "2016-06-29T06:07:25Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Werner\_Flamme](https://avatars.discourse-cdn.com/v4/letter/w/c68b51/32.png) [@Werner\_Flamme](https://forum.ansible.com/u/Werner_Flamme)\
**Post date:** [June 29, 2016, 6:07am UTC](https://forum.ansible.com/t/question-on-lineinfile-module/21884/1 "2016-06-29T06:07:25Z")

</div>

Hi everyone,

I have one play that does not do what I want it to:

- name: set kernel multiversions  
&nbsp;&nbsp;lineinfile:  
&nbsp;&nbsp;&nbsp;&nbsp;dest: /etc/zypp/zypp.conf  
&nbsp;&nbsp;&nbsp;&nbsp;line: "multiversion.kernels = latest,oldest,running"  
&nbsp;&nbsp;&nbsp;&nbsp;regexp: "multiversion.kernels = latest,latest-1,running"  
&nbsp;&nbsp;&nbsp;&nbsp;state: present

I expect  
-\> the module scans for a line matching "regex"  
-\> if this is found, the found line is replaced with "line"  
-\> if "regex" has no matches, nothing is done

The module instead scans the file, and on the first run it behaves as I  
expect, the line in the file is modified. On subsequent runs, one line  
(per run) is added to the file (before EOF), so that I have multiple  
lines containing "line".

Is this behaviour expected? How can I make a replacement only when  
"regex" matches?

When using a registered variable, this variable is shown as:

ok: [hostname] =\> {  
&nbsp;&nbsp;&nbsp;&nbsp;"myrole\_var1": {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"backup": "",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"changed": true,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"diff": [  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"after": "",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"after\_header": "/etc/zypp/zypp.conf (content)",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"before": "",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"before\_header": "/etc/zypp/zypp.conf (content)"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"after\_header": "/etc/zypp/zypp.conf (file attributes)",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"before\_header": "/etc/zypp/zypp.conf (file attributes)"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;],  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"msg": "line added"  
&nbsp;&nbsp;&nbsp;&nbsp;}  
}

So nothing I could use "when" on.

I use the blockinfile module to add a line in this file, but I do not  
see how to use this module to replace one line. This module runs only  
once, on subsequent runs it says "OK" instead of "Changed".

Regards,  
Werner

---

<div class="post-metadata">

**Author:** ![Kai\_Stian\_Olstad](https://avatars.discourse-cdn.com/v4/letter/k/e19adc/32.png) [@Kai\_Stian\_Olstad](https://forum.ansible.com/u/Kai_Stian_Olstad)\
**Post date:** [June 29, 2016, 1:21pm UTC](https://forum.ansible.com/t/question-on-lineinfile-module/21884/2 "2016-06-29T13:21:48Z")

</div>

No, and you are not alone  
[https://github.com/ansible/ansible-modules-core/issues/3975](https://github.com/ansible/ansible-modules-core/issues/3975)

---

<div class="post-metadata">

**Author:** ![jdelaporte](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/jdelaporte/32/366_2.png) [@jdelaporte](https://forum.ansible.com/u/jdelaporte)\
**Post date:** [June 29, 2016, 6:59pm UTC](https://forum.ansible.com/t/question-on-lineinfile-module/21884/3 "2016-06-29T18:59:16Z")

</div>

Hi Werner,

You would want to use the backrefs feature of the lineinfile module. Here is an example that I use for deleting root password hashes from the /etc/shadow file. I use regex numbered groups (with parens and \1, etc) to capture and replay existing parts of lines as needed:

- name: delete root password  
lineinfile: ‘dest=/etc/shadow  
backup=yes  
backrefs=yes  
regexp=“^(root):._?:(._)$”  
line=“\1:\*:\2”’

And another example (two tasks) that update an ntp config with a new IP address:

# The following two tasks will replace existing ntp config from .135 to .133

- name: Fix ntp.conf  
lineinfile: dest=/etc/ntp.conf  
backup=yes  
state=present  
backrefs=yes  
regexp=‘^(._server._) 192.168.1.135’  
line=‘\1 192.168.1.133’
- lineinfile: dest=/etc/ntp.conf  
state=present  
backup=yes  
backrefs=yes  
regexp=‘^(._restrict._) 192.168.1.135’  
line=‘\1 192.168.1.133’

---

<div class="post-metadata">

**Author:** ![Werner\_Flamme](https://avatars.discourse-cdn.com/v4/letter/w/c68b51/32.png) [@Werner\_Flamme](https://forum.ansible.com/u/Werner_Flamme)\
**Post date:** [June 30, 2016, 6:20am UTC](https://forum.ansible.com/t/question-on-lineinfile-module/21884/4 "2016-06-30T06:20:06Z")

</div>

Kai Stian Olstad [29.06.2016 15:21]:

> > The module instead scans the file, and on the first run it behaves as I  
> > expect, the line in the file is modified. On subsequent runs, one line  
> > (per run) is added to the file (before EOF), so that I have multiple  
> > lines containing "line".
> > 
> > Is this behaviour expected? How can I make a replacement only when  
> > "regex" matches?
> 
> No, and you are not alone  
> [https://github.com/ansible/ansible-modules-core/issues/3975](https://github.com/ansible/ansible-modules-core/issues/3975)

Yes, that's exactly what happens here. Thank you for pointing me there.

I already thought of using an "absent" and a "present" task, but now I  
use the replace module, and it seems to work:

- name: replace kernel multiversions  
&nbsp;&nbsp;replace:  
&nbsp;&nbsp;&nbsp;&nbsp;dest: /etc/zypp/zypp.conf  
&nbsp;&nbsp;&nbsp;&nbsp;regexp: "^multiversion.kernels = latest,latest-1,running"  
&nbsp;&nbsp;&nbsp;&nbsp;replace: "multiversion.kernels = latest,oldest,running"

BTW, I'm running ansible version 2.1.0.0, and it's the first time I use  
the lineinfile module (since I'm quite new to ansible).

Regards,  
Werner

---

<div class="post-metadata">

**Author:** ![Werner\_Flamme](https://avatars.discourse-cdn.com/v4/letter/w/c68b51/32.png) [@Werner\_Flamme](https://forum.ansible.com/u/Werner_Flamme)\
**Post date:** [June 30, 2016, 6:43am UTC](https://forum.ansible.com/t/question-on-lineinfile-module/21884/5 "2016-06-30T06:43:17Z")

</div>

Hi Joanna,

so using lineinfile with regexp, but without backrefs will duplicate a  
line and lineinfile with regexp and backrefs will not? Indeed, it seems  
to be like that.

- name: another replacement attempt  
&nbsp;&nbsp;lineinfile:  
&nbsp;&nbsp;&nbsp;&nbsp;dest: /etc/zypp/zypp.conf  
&nbsp;&nbsp;&nbsp;&nbsp;backrefs: yes  
&nbsp;&nbsp;&nbsp;&nbsp;regexp: '^(multiversion.kernels = latest),(latest-1),(running)$'  
&nbsp;&nbsp;&nbsp;&nbsp;line: '\1,oldest,\3'  
&nbsp;&nbsp;&nbsp;&nbsp;state: present

works as expected and does not create a duplicate line if regexp is not  
found. The registered variable shows '"changed": false'.

I added that to the bug report...

This behaviour is not documented on  
\<[http://docs.ansible.com/ansible/lineinfile\_module.html&gt;](http://docs.ansible.com/ansible/lineinfile_module.html&gt;), so I consider  
this as an error.

Werner

Joanna Delaporte [29.06.2016 20:59]:
