I am trying to edit a string in a multi-line file. For instance, if I had this string:
This is a file and I am editing it
I want to add the string “new” in front of file if it does not exist already.
I’ve tried lineinfile, but the issue is that I don’t know what else is on the line. There could be more data after “This is a file and I am editing it” that I don’t want to change. What is the best way to do this?
Here’s one solution. It uses backrefs and a negative lookahead assertion.
- name: Test lineinfile
hosts: localhost
gather_facts: false
tasks:
- name: Create a file to work on
ansible.builtin.copy:
content: |
First line of a file
Second line of the same file
This is a file and I am editing it. Extra Stuff!
Fourth line of this file
dest: /tmp/textfile.txt
- name: Show the file content
ansible.builtin.debug:
msg: "{{ lookup('file', '/tmp/textfile.txt') }}"
- name: Insert "new" before "file" in the 3rd line
ansible.builtin.lineinfile:
path: /tmp/textfile.txt
regexp: '(This is a )(?!>new)(file and I am editing it\..*)'
backrefs: true
line: 'new '
- name: Show the file content a 2nd time
ansible.builtin.debug:
msg: "{{ lookup('file', '/tmp/textfile.txt') }}"
- name: Second identical lineinfile should not make changes
ansible.builtin.lineinfile:
path: /tmp/textfile.txt
regexp: '(This is a )(?!>new)(file and I am editing it\..*)'
backrefs: true
line: 'new '
- name: Show the file content a 3nd time
ansible.builtin.debug:
msg: "{{ lookup('file', '/tmp/textfile.txt') }}"