I'm trying to add value to a line and getting odd results.
Original line (may change value):
SomeParam=test
Code:
- name: Add info
win_lineinfile:
path: file_path
backrefs: yes
regexp: '(SomeParam=*)'
line: '\1,added info'
Result:
\1,added info
Expected result:
SomeParam=test,added info
There are two issues here.
Firstly, in the Windows version of lineinfile (i.e. win_lineinfile), you need to use $1 instead of \1 as a back reference.
Secondly, your regular expression should be (SomeParam=.*) and not (SomeParam=*) -- the latter will match SomeParam followed by zero or more = signs, whereas the former will match SomeParam= followed by zero or more characters.
Taking into consideration the above, try the following:
- name: Add info
win_lineinfile:
path: file_path
backrefs: yes
regexp: '(SomeParam=.*)'
line: '$1,added info'
Related
I'm using a win_lineinfile module and trying to use manual newline characters. It works just fine if the line argument of the module is only on one line but the moment I use multiline it breaks.
I'm trying to do this
- name: Something
win_lineinfile:
path: some_path
line: |
firstline\r\n
secondline
but it doesn't work.
This does but I lose the ability of using multiline string.
- name: Something
win_lineinfile:
path: some_path
line: firstline\r\nsecondline
I'm running an ansible playbook that allows me to (or should allow me to) replace two lines in a configuration file for a remote server. Most of the file replacements are dictionary style entries where neither the key nor the value have quotes. But there is one replacement where the name needs to be quoted. Here is the task from the ansible playbook:
- name: Enable traefikExporter within vars.jsonnet configuration file.
ansible.builtin.replace:
path: /home/bill/cluster-monitoring/vars.jsonnet
regexp: "name: 'traefikExporter',[\n\r].*[\n\r]"
replace: |6
name: 'traefikExporter',
enabled: true,
The error thrown is:
The offending line appears to be
replace: |6
name: 'traefikExporter'
^ here
and it notes that it is a mismatched quote. But I've tried changing the yaml replace parameter to > and using \n for line breaks on a single line as well as the | with quoted lines. They all throw versions of the mismatched quote error.
For reference, the following task, which is immediately above this task, runs correctly without errors:
- name: Enable k3s Monitoring within vars.jsonnet configuration file.
ansible.builtin.replace:
path: /home/bill/cluster-monitoring/vars.jsonnet
regexp: "\ k3s: {[^}]*},"
replace: |2
k3s: {
enabled: true,
master_ip: ['192.168.2.139'],
},
The closest thing I could find is here, but this didn't work. In both cases the regexp covers multiple lines and the replace covers the same lines identified by the regexp. What am I missing?
update
I also tried replacing the replacement text and now believe that the actual formatting issue is in the regexp: "name: 'traefikExporter',[\n\r].*[\n\r]" line. No matter what I place in the replace line it throws the error. I think the quotes in the regexp are the issue.
work around
I came up with a work around but it still isn't right. The following is very close to what I'd like - but a bit frustrated that it isn't exactly what I expected:
- name: Enable traefikExporter within vars.jsonnet configuration file.
ansible.builtin.replace:
path: /home/bill/cluster-monitoring/vars.jsonnet
regexp: "name: 'traefikExporter',[\n\r].*"
replace: >4
name: 'traefikExporter',
enabled: true,
The |6 or >6 was the problem - but not sure why. My expected behavior was to have a 6 space indent. But this is the thing throwing the error. When I put it to 4 there is no quote error. But as you can see - to get the formatting right I have to do some weird spacing (the name: is the correct indentation with the 4, but I have to add 6 actual spaces to get the next line to align. Not part of this question - but neither the | nor the > seems to impact the trailing return in both cases there is an extra line after the replacement.
YAML processes escape sequences in double-quoted scalars, so you should use
regexp: "name: 'traefikExporter',[\\n\\r].*[\\n\\r]"
I suggest however to use a block scalar to avoid escaping hell:
regexp: >-
name: 'traefikExporter',[\n\r].*[\n\r]
Regarding the indentation indicator, this cannot work:
replace: |6
name: 'traefikExporter',
enabled: true,
You are basically saying „the following block scalar has 6 spaces indentation in addition to the indentation of the replace: key“. However, it only has two, which makes the YAML parser immediately drop out of block scalar parsing mode. The following error results from the YAML parser trying to interpret what you intend to be the block scalar's content as part of the YAML structure.
I suggest doing:
replace: |-2
name: 'traefikExporter',
enabled: true,
to give the block scalar 2 space in front of each line (which seems to be what you want) and also to remove the trailing newline (with the -).
I want to remove last three lines of file using ansible. I tried using lineinfile but it removed all the lines from file. I have posted below my file and ansible-playbook. I want to remove nfs_config, nfs_share and mount_path using lines using ansible.Thanks in advance.
file.txt
[images]
[tickets]
[unix sockets]
[nfs_config]
nfs_share=
mount_path=
Ansible-playbook
- name: Remove mount path from daemon.conf for clean-daemon
linefile:
path: /etc/ovirt-imageio-daemon/daemon.conf
regexp: "[nfs_config]"
state: absent
Use ini_file. The task below will remove the nfs_config section from the configuration file
- ini_file:
path: /etc/ovirt-imageio-daemon/daemon.conf
section: nfs_config
state: absent
regexp: "[nfs_config]" is not doing what you want, you need to use "[nfs_config]", otherwise you are matching any character that is between the []. This is why it's removing multiple lines.
https://docs.python.org/2/library/re.html
Also, just make 3 lineinfile command to match nfs_config, nfs_share and mount_path
You could use onee lineinifile with a complex regex to match them all, but it will be easier to read/maintain with 3 that are clear.
I have to change
`<!--<parameter name=\"HostnameVerifier\">DefaultAndLocalhost</parameter>-->`
to
<!--<parameter name=\"HostnameVerifier\">AllowAll</parameter>--> in APIM_HOME/repository/conf/axis2/axis2.xml.
I am using
- name: "Modify HostnameVerifier"
lineinfile:
dest: "/home/ec2-user/ansible-test/wso2am-2.0.0/repository/conf/axis2/axis2.xml"
state: "present"
line: "\t\t<parameter name=\"HostnameVerifier\">AllowAll</parameter>"
regexp: "<!--<parameter name=\"HostnameVerifier\">DefaultAndLocalhost</parameter>-->"
This is only replacing the 3rd occurrence of the regexp. I want it to replace only 2nd occurrence. How do I do that?
You can't do this with lineinfile. From the docs:
...only the last line found will be replaced...
And lineinfile iterates line-by-line – you can't add more context to it.
You should use replace module and add more context to the regexp to match exatly that part of file you want to modify. You can use multiline patterns here.
I have a file called authorized_keys. I need to delete a particular line using an Ansible script.
The problem is when I try to remove a line that includes a '+' character. Ansible is not able to remove this line.
e.g authorized_keys file is:
.....
abhi foo+bar saken
......(EOF)
I want to remove the abhi foo+bar saken line but Ansible is not removing this line because of the + character.
I am able to remove lines that do not contain a + character .
Task:
- name: Delete keys in sysadmin/.ssh/authoriezd_keys
lineinfile: dest=/home/{{name}}/.ssh/authorized_keys
state=absent
regexp='^{{key}}$'
PS: I am using Ansible's lineinfile module
The problem probably is that + has a meaning in a regular expression.
You should be able to fix it by escaping the +. If you can't do that from the source where {{ key }} is defined, you can escape it with the replace Jinja filter:
- name: Delete keys in sysadmin/.ssh/authoriezd_keys
lineinfile: dest=/home/{{name}}/.ssh/authorized_keys
state=absent
regexp='^{{ key | replace("+", "\+") }}$'
You might run into more problems if {{ key }} contains other characters which have a meaning in regular expressions. If that's the case I think the safe way would be to create your own filter plugin where you simply return the input passed through re.escape.