简体   繁体   中英

regex ansible lineinfile subsection

I am fairly new to ansible and have been solving the following problem with a shell script, but the proper way I believe is to use the lineinfile module, just not sure how to accomplish this.

Let's say I have a file with the following text in it.

<cpu>
   <alarm>
      active = yes
   </alarm>
</cpu>
<disk>
   <alarm>
      active = yes
      <fixed>
         <#>  
            active = yes
            description = File system /
            <inode_error>
               active = yes
               threshold = 2
               message = InodeError
            </inode_error>
         </#>
         <#boot>
            active = yes
            description = File system /boot
            percent = yes
            <error>
               active = yes
               threshold = 5
               message = DiskError
            </error>
         </#boot>
      </fixed>
   </alarm>
</disk>

I want to make sure the following section is set correctly.

<disk><alarm><fixed><#boot><error>"threshold = 2"</error></#boot></fixed></alarm></disk>

is there a way to only (modify/make sure exists) that line, normally this file is much larger with many more sections, but I erased some so the question is readable.

Update: Modifying this as it is not valid XML and the XML module will not parse the file correctly.

Thanks!

lineinfile scans file per line, so you can't define complex multiline regexp for context definition.

replace module support multiline regexp.

If you have threshold = X in the file and want to be sure it is set to specific value, you can use this regexp:

- replace:
    path: ./test.txt
    regexp: '(<disk>[\s\S]*<alarm>[\s\S]*<#boot>[\s\S]*<error>[\s\S]*)(threshold\s*=\s*\d+)([\s\S]*?<\/error>)'
    replace: '\1threshold = 2\3'

It searches for line threshold\\s*=\\s*\\d+ inside <disk>...<alarm>...<#boot>...<error>... . This code is idempotent – so if threshold = 2 , then nothing is done.

But if there is no threshold = X string, it will fail. You should construct more complex regular expression for that case.

you could use the lineinfile module ( http://docs.ansible.com/ansible/latest/lineinfile_module.html ) where you could write a regex to modify/add the line and use the validate function to run a command to ensure that the xml file has the proper syntax.

If you are on Ansible 2.4 you can use the xml module ( https://docs.ansible.com/ansible/2.4/xml_module.html ) and use the attribute parameter to check if the xpath in xml file is set, like that:

- name: Read attribute value
  xml:
    path: /foo/bar.xml
    xpath: /business/website/validxhtml
    content: attribute
    attribute: validatedon
  register: xmlresp

regards

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM