ferdinand
ferdinand

Reputation: 21

ansible regexp for replace space quotes or comment

I have a file that contain multiple row. One of these lines may look like this:

item = 1000 or item = "1000" or item='1000' #with comment same line 
or item = "1000'

or every possible combinations regarding the spaces around the equal sign, or with single or double quotes or without quotes or, again, with or without comments on the same line.

In short, I only have to take the number and set a variable with set fact. This thing is driving me crazy.

Sorry but I don't put all the attempts I made because they would be too many.

myfile.conf:  
 start = 'before'
 stop=after  
 item =100  #changed  
 bool= "yes"
 class = 'first"
 author = "Scott"

or item = 1000 or item = "1000" or item='1000' #blalala or item = "1000'
As stated above.

This is the last attempt before giving up:

- name: QUERY- read the myfile.conf
  ansible.builtin.shell: cat "{{ './myfile.conf' }}"
  register: resultline
  
- name: regex
  ansible.builtin.set_fact:
    mynumber: |-
      {{
          resultline.stdout |
          regex_search("^item *=*.*", multiline=True) |
          regex_replace(".*=*['\"](.*)['\"]*$", '\1')
      }}

And, of course, this not work...

Expected result is: 
mynumber = 1000 

Upvotes: 1

Views: 1265

Answers (1)

Vladimir Botka
Vladimir Botka

Reputation: 67984

Given the file below. (I fixed the quotation of *class* value.)

shell> cat myfile.conf
 start = 'before'
 stop=after  
 item =100  #changed  
 bool= "yes"
 class = "first"
 author = "Scott"

Q: "The var mynumber with the number after the = at the line that starts with item."

A: Read the file

    - command: cat myfile.conf
      register: resultline

Remove comments and create the list

conf_list: "{{ resultline.stdout_lines|
               map('regex_replace', conf_regex, conf_replace)|
               list }}"
conf_regex: '^(.*)#.*$'
conf_replace: '\1'

gives

conf_list:
  - ' start = ''before'''
  - ' stop=after  '
  - ' item =100  '
  - ' bool= "yes"'
  - ' class = "first"'
  - ' author = "Scott"'

Replace '=' by ': ' and create the dictionary

conf_dict: "{{ conf_list|
               map('regex_replace', '=', ': ')|
               join('\n')|
               from_yaml }}"

gives

conf_dict:
  author: Scott
  bool: 'yes'
  class: first
  item: 100
  start: before
  stop: after

Set the variable

my_number: "{{ conf_dict.item }}"

gives

my_number: '100'

The result of the evaluation "{{ }}" is always a string. You can convert it to an integer. For example,

    - debug:
        var: my_number|int + 1

gives

my_number|int + 1: '101'

Notes

  • Example of a complete playbook
- hosts: localhost
  vars:
    conf_list: "{{ resultline.stdout_lines|
                   map('regex_replace', conf_regex, conf_replace)|
                   list }}"
    conf_regex: '^(.*)#.*$'
    conf_replace: '\1'
    conf_dict: "{{ conf_list|
                   map('regex_replace', '=', ': ')|
                   join('\n')|
                   from_yaml }}"
    my_number: "{{ conf_dict.item }}"
  tasks:
    - command: cat myfile.conf
      register: resultline
    - debug:
        var: my_number
    - debug:
        var: my_number|int + 1
  • The value of the attribute item is an integer
    - debug:
        var: conf_dict.item|type_debug

gives

conf_dict.item|type_debug: int

You can use it in arithmetic operations without conversion. For example,

    - debug:
        var: conf_dict.item + 1

gives

conf_dict.item + 1: '101'

Upvotes: 1

Related Questions