I need to replace lines in /etc/fstab using the following logic:
if line contains “ext4”; then
if line ends in “0 0”; then
replace “0 0” with “1 2”
I can easily do this with sed:
sed ‘/ext4/s/0 0$/1 2/’
But from what I can tell the lineinfile and replace modules accept only one regexp, not two. How would I do this in ansible without using the script or command modules?
# See [https://docs.python.org/3/library/re.html](https://docs.python.org/3/library/re.html) for further details on syntax
- name: Use backrefs with alternative group syntax to avoid conflicts with variable values
ansible.builtin.lineinfile:
path: /tmp/config
regexp: ^(host=).*
line: \g<1>{{ hostname }}
backrefs: yes
Can you use backrefs to incorporate part of the found regexp in the new line?
Thank you, Walter. I always enjoy reading your solutions.
This is where exactness matters and can become a rabbit hole very quickly depending on how much of your environment is a wild wild west.
SUCCENCT DEFINITION: The match should be the 3rd argument (ARG3) in /etc/fstab equal to “ext4” of any lines not beginning with “#” with ARG5 and ARG6 = “0”.
Depending on the risk you’re willing to accept, /etc/fstab has six white-space delimited arguments.
ARG1\s+ARG2\s+ARG3\s+ARG4\s+ARG5\s+ARG6
When ARG3 = ext4 and ARG5 and ARG6 = 0
then
ARG1 ARG2 ext4 ARG4 1 2
backrefs will help keep it straight.
regexp: “^(.)\s+(.)\s+ext4\s+(0)\s+(0)$”
replace: “\1 \2 ext4 \4 1 2”
Do you agree this is more exact and better declaratively? Probably way more than Cy Schubert really wanted.
You have to test it. The regex wants to match the longest string possible and .* matches everything. If the regex I typed works, go with it. You can overthink it and spend cycles trying to get something to work when a simpler regex might have been sufficient.