How to replace a line with special characters to another line with special characters using variables?

2,511 views
Skip to first unread message

Ankit

unread,
Oct 23, 2019, 2:35:35 AM10/23/19
to Ansible Project
Hello All,

I am trying to update a configuration file where there are existing lines (rules) with special characters (:*[]/\. etc.). In normal scenario, i can always manually escape all the characters but in this particular case, i have got pre-populated values in two variables: var1 contains the text to replace and var2 contains the new text which needs to be updated instead of value in var1.

For Example. The following is one sample config file where i want to replace [monitor://D:\Logs\Org.SNP.Publisher\*]  to   [monitor://D:\new\path\dir\*]

------------
index
= idx_dom_<AIRID>_<APP_NAME>

[monitor://D:\logs\inetpub\logs\LogFiles\W3SVC2\*.log]
sourcetype
= /stg/4552/api/iis_logs
disabled
= false

[monitor://D:\Logs\Org.SNP.Publisher\*]
sourcetype
= /stg/4552/app/Org.SNP.Publisher
disabled
= false

and my playbook is getting the variables during run time (using awx surveys).

---
- hosts: all
  gather_facts
: false
  vars
:
   
var1: '[monitor://D:\Logs\Org.SNP.Publisher\*]'
   
var2: '[monitor://D:\new\path\dir\*]'
  tasks
:
     
- name: test unsafe variable in the file
        replace
:
          path
: /home/anks/yaml/filewithcontent
          regexp
: '{{ var1 | regex_escape() }}'
          replace
: "{{ var2 }}"
...

I have been trying different things like unsafe! , regex_replace() but it doesn't seem to work. Could anyone please suggest how can i achieve this?

Regards,
Ankit

Ankit

unread,
Oct 24, 2019, 5:32:05 AM10/24/19
to Ansible Project
Hello All,

Can anyone please suggest how can i get this done.

Thanks in advance.

Kai Stian Olstad

unread,
Oct 24, 2019, 2:45:25 PM10/24/19
to ansible...@googlegroups.com
On 23.10.2019 08:35, Ankit wrote:
> ---
> - hosts: all
> gather_facts: false
> vars:
> *var1:* '[monitor://D:\Logs\Org.SNP.Publisher\*]'
> *var2**:* '[monitor://D:\new\path\dir\*]'
> tasks:
> - name: test unsafe variable in the file
> replace:
> path: /home/anks/yaml/filewithcontent
> regexp: '{{ *var1 *| regex_escape() }}'
> replace: "{{ *var2 *}}"
> ...
>
> I have been trying different things like *unsafe!* , *regex_replace()* but
> it doesn't seem to work. Could anyone please suggest how can i achieve this?

Replace module is using Python re[1] module.
Your replace: contain escape sequences, if Python re recognize a escape sequence it will replace it.

You have \n, \b and \d of these Python re do recognize \n at least, so you need to be escaped it by putting an extra \ in it so it becomes \\n


[1] https://docs.python.org/2/library/re.html

--
Kai Stian Olstad

Ankit Vashistha

unread,
Oct 28, 2019, 1:48:50 AM10/28/19
to Ansible Project
Hello Kai,

Thanks for your response.
Actually the issue here is that these pattern value and replace text values are provided to the playbook using surveys i.e., during run time and hence, it won't be possible to manually escape them by the users who run the template.

Is there a way to auto escape  any special chars in the pattern and replace the text without escaped values in the file?

Regards,
Ankit


--
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/9dab55f4-2443-88a7-8fda-2c58131254e4%40olstad.com.

Kai Stian Olstad

unread,
Oct 29, 2019, 6:06:13 PM10/29/19
to ansible...@googlegroups.com
On 28.10.2019 06:48, Ankit Vashistha wrote:
> Hello Kai,
>
> Thanks for your response.
> Actually the issue here is that these pattern value and replace text
> values
> are provided to the playbook using surveys i.e., during run time and
> hence,
> it won't be possible to manually escape them by the users who run the
> template.
>
> Is there a way to auto escape any special chars in the pattern and
> replace
> the text without escaped values in the file?

You could write your own filter that escapes every escape sequences
Python regexp has or change the replace module to also accept plain text
aka automatically escape all escapes sequence.

A workaround is to use the regex_replace filter, this is only for \n,
but you would need to do it for every escape sequence(there are many of
them)



- name: test unsafe variable in the file
replace:
path: /home/anks/yaml/filewithcontent
regexp: '{{ var1 | regex_escape() }}'
replace: "{{ var2 | regex_replace('\\\\n', '\\\\\\\\n') }}"

--
Kai Stian Olstad

Vladimir Botka

unread,
Oct 30, 2019, 12:53:14 AM10/30/19
to Ankit, ansible...@googlegroups.com
On Thu, 24 Oct 2019 02:32:05 -0700 (PDT)
Ankit <ankitva...@gmail.com> wrote:

> > replace [monitor://D:\Logs\Org.SNP.Publisher\*]
> > to [monitor://D:\new\path\dir\*]
> >
> > ---
> > - hosts: all
> > gather_facts: false
> > vars:
> > *var1:* '[monitor://D:\Logs\Org.SNP.Publisher\*]'
> > *var2**:* '[monitor://D:\new\path\dir\*]'
> > tasks:
> > - name: test unsafe variable in the file
> > replace:
> > path: /home/anks/yaml/filewithcontent
> > regexp: '{{ *var1 *| regex_escape() }}'
> > replace: "{{ *var2 *}}"
> > ...

Try this

- replace:
path: 'playbook.yml'
regexp: '{{ regex }}'
replace: '{{ replace }}'
vars:
regex: '\[monitor\://D\:\\Logs\\Org\.SNP\.Publisher\\\*]'
replace: '[monitor://D:\\new\\path\\dir\\*]'


1) Put *regex* and *replace* into separate variables and use "7.3.2.
Single-Quoted Style".
Quoting: '...the “\” and “"” characters may be freely used. This restricts
single-quoted scalars to printable characters ...'
https://yaml.org/spec/1.2/spec.html#id2788097

2) In *regex* escape Python regular expressions special characters only
https://pythex.org/

3) In *replace* escape control characters only
https://en.wiktionary.org/wiki/Appendix:Control_characters

Cheers,

-vlado
Reply all
Reply to author
Forward
0 new messages