Using lineinfile to append items to the END of a line

49 views
Skip to first unread message

TheSmiths

unread,
Sep 11, 2019, 10:06:27 AM9/11/19
to Ansible Project
Hi,

I would like to use lineinfile module to do the next:

1. go over list of items (with_items)
2. look for specific line that always starts with the word "ALL:"  (hosts.allow)
3. append each item at the END of the line with comma before the item

for example


Thanks,
Morrissey
 

Philippe Eveque

unread,
Sep 12, 2019, 1:26:29 AM9/12/19
to ansible...@googlegroups.com
I would recommend  the Template module to do it

while technically possible with lineinfile, the regular expression to do it will be overly complex 
and hard to read/maintain

--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/12fd72e2-f7cb-4911-b4c5-dcc4ce9b3f97%40googlegroups.com.

Shivharsh Singh

unread,
Sep 12, 2019, 3:15:24 AM9/12/19
to Ansible Project
Hello Morrissey,

You may use the below playbook to fulfill your requirements. It makes use of lineinfile module with regular expression to capture the line to be modified.

---
- hosts: localhost
  connection
: local
  gather_facts
: false
  tasks
:
     
- name: "insert values to a list"
       lineinfile
:
           dest
: /opt/test.txt
           regexp
: '(^ALL.*$)'
           line
: '\1, {{item}}'
           backrefs
: yes
       with_items
:
           
- 1.1.1.1/255.255.255.255
           
- 2.2.2.2/255.255.255.255

The file would be modified as shown below: 
Hello world !
ALL
, 1.1.1.1/255.255.255.255, 2.2.2.2/255.255.255.255
This is a test file

Hope this is helpful !

Thanks,
Shivharsh

Dick Visser

unread,
Sep 12, 2019, 6:27:48 AM9/12/19
to ansible...@googlegroups.com
This will work, but it's not idempotent.
So if you run it again it will add the two CIDRs again.
For it to work idempotently, the regex will need to match both what
you have before and what you get after.
Something like this should work:


---
- hosts: localhost
connection: local
gather_facts: false
vars:
cidrs:
- 1.1.1.1/255.255.255.255
- 2.2.2.2/255.255.255.255

tasks:
- name: "insert values to a list"
lineinfile:
dest: /tmp/test.txt
regexp: "^(?P<start>ALL:.*?)((,{{ cidrs | join(',') }})*)$"
line: "\\g<start>,{{ cidrs | join(',') }}"
backrefs: yes


The named group 'start' is to avoid clashing with a CIDR that begins
with a number.


Dick
> --
> You received this message because you are subscribed to the Google Groups "Ansible Project" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/acbe7f26-fea5-403b-92f3-b8e2c1506b1a%40googlegroups.com.



--
Dick Visser
Trust & Identity Service Operations Manager
GÉANT

Philippe Eveque

unread,
Sep 12, 2019, 10:08:32 AM9/12/19
to ansible...@googlegroups.com
not idempotent when the list ordering change, plus some others
 
for each item in the list you have to add it if not already there (requires a look-ahead expression in regex)
that is what make it quite complex at the end, but doable as long as
per the spec the only need is to append to an existing list.

hence the idea to leverage the template module
that also can deal with removal of item from the list

--
Phil


Reply all
Reply to author
Forward
Message has been deleted
Message has been deleted
0 new messages