Crooks_
Crooks_

Reputation: 99

How to conditionally replace text in a list with regex_replace?

I have a variable in my playbook that's derived from a list. In some instances this variable contains a "-" to separate two values. For example,

Numbers:
  - 2211
  - 2211-2212

When this is the case I would like to replace the "-" with a "_" based on a conditional: If the number is 4 characters long, do this. Else, replace the "-" with a " _ " and do that.

I've already tried to fiddle around with jinja2 ans regex in my playbooks but so far no luck. Here's what I tried,

number: {% if length(item) == 4 %} {{ item | regex_replace("^(.*)$", "Number_\1") | string }} {% else %} {{ item | regex_replace("^(.*)$", "Number_\1") |replace("-", "_") | string }}

The result that I would like to have,

Number is four characters long:
    number: Number_2211
Number is more then 4 characters long:
    number: Number_2211_2212 

Some of the Error messages I have received are,

ERROR! Syntax Error while loading YAML.
  did not find expected key

ERROR! Syntax Error while loading YAML.
  found character that cannot start any token

Is there a way to achieve this within the Ansible playbook? Thanks in advance!

Upvotes: 2

Views: 10658

Answers (2)

larsks
larsks

Reputation: 312510

It's not really clear how you're trying to use this data. Ansible isn't great at modifying complex data structures in place, but it has lots of way of transforming data when you access it. So for example, this playbook:

---
- hosts: localhost
  gather_facts: false
  vars:
    numbers:
      - "2211"
      - "2211-2212"
  tasks:
    - debug:
        msg: "number: {{ item.replace('-', '_') }}"
      loop: "{{ numbers }}"

Will output:

TASK [debug] **********************************************************************************
ok: [localhost] => (item=2211) => {
    "msg": "number: 2211"
}
ok: [localhost] => (item=2211-2212) => {
    "msg": "number: 2211_2212"
}

If you really need to make the transformation conditional on the length (and it's not clear that you do), you could do something like:

- debug:
    msg: "{{ item.replace('-', '_') if item|length > 4 else item }}"
  loop: "{{ numbers }}"

Update

I see you've selected the other answer. The solution presented here seems substantially simpler (there is no "incomprehensible sequence of filters, regex expressions, and equality checks"), and produces almost identical output:

TASK [debug] **********************************************************************************
ok: [localhost] => (item=445533) => {
    "msg": "445533"
}
ok: [localhost] => (item=112234-538) => {
    "msg": "112234_538"
}
ok: [localhost] => (item=11) => {
    "msg": "11"
}
ok: [localhost] => (item=1111) => {
    "msg": "1111"
}
ok: [localhost] => (item=1111-1111) => {
    "msg": "1111_1111"
}
ok: [localhost] => (item=11-11) => {
    "msg": "11_11"
}

It's not clear, given 11-11, whether you expect 11_11 or 11-11 as output. If you expect the former, this answer is more correct.

Upvotes: 3

Nick
Nick

Reputation: 2034

You can use an incomprehensible sequence of filters, regex expressions, and equality checks to do this.

#!/usr/bin/env ansible-playbook
- name: Lets munge some data
  hosts: localhost
  gather_facts: false
  become: false
  vars:
    array:
    - 445533
    - 112234-538
    - 11
    - 1111
    - 1111-1111
    - 11-11
  tasks:
  - name: Replace hypens when starting with 4 numbers
    debug:
      msg: "{{ ((item | string)[0:4] | regex_search('[0-9]{4}') | string != 'None') 
             | ternary((item | regex_replace('-', '_')), item) }}"
    loop: "{{ array }}"

PLAY [Lets munge some data] *****************************************************************************************************************************************************************************************************

TASK [Replace hypens when starting with 4 numbers] ******************************************************************************************************************************************************************************
ok: [localhost] => (item=445533) => {
    "msg": "445533"
}
ok: [localhost] => (item=112234-538) => {
    "msg": "112234_538"
}
ok: [localhost] => (item=11) => {
    "msg": "11"
}
ok: [localhost] => (item=1111) => {
    "msg": "1111"
}
ok: [localhost] => (item=1111-1111) => {
    "msg": "1111_1111"
}
ok: [localhost] => (item=11-11) => {
    "msg": "11-11"
}

PLAY RECAP **********************************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0   

Upvotes: 2

Related Questions