Home > Enterprise >  Parse json value when value contains a string in ansible
Parse json value when value contains a string in ansible

Time:04-29

This ansible playbook works

---
- hosts: localhost
  gather_facts: False

  vars:
    jq: "[?contains(name, 'Pizza')]"
    json: |
       [{
            "name": "Ted's Sub Shop - 720895714701",
            "templateid": "24632"
        },
        {
            "name": "Ted's Pizza - 720895714702",
            "templateid": "24663"
        }]

  tasks:
  - name: DEBUG
    debug:
      msg: "{{ json | from_json | json_query(jq) }}"

It returns the following

ok: [localhost] => {
    "msg": [
        {
            "name": "Ted's Pizza - 720895714702",
            "templateid": "24663"
        }
    ]
}

I need to take it a few steps further and when the value of name contains Pizza I need it to return just the 12 digit number on the end. So the return output would look like this

ok: [localhost] => {
    "msg": "720895714702"
}

Thoughts?

CodePudding user response:

you could try

- name: testplaybook jinja2
  hosts: localhost
  gather_facts: no
  vars:
    json: |
       [{
            "name": "Ted's Sub Shop - 720895714701",
            "templateid": "24632"
        },
        {
            "name": "Ted's Pizza - 720895714702",
            "templateid": "24663"
        }]
  tasks:
    - name: DEBUG
      debug:
        msg: "{{ json | from_json | selectattr('name', 'contains' , 'Pizza') 
                                  | map(attribute='name') 
                                  | map('regex_replace', '^.*?(\\d*)$', '\\1')}}" 

result:

ok: [localhost] => {
    "msg": [
        "720895714702"
    ]
}

CodePudding user response:

It might be more efficient to add an attribute. For example the declaration below

    json_id: "{{ json|zip(id_hash)|map('combine')|list }}"
    id_hash: "{{ id_list|
                 map('community.general.dict_kv', 'id')|list }}"
    id_list: "{{ json|
                 map(attribute='name')|
                 map('split', '-')|
                 map('last')|
                 map('int')|list }}"

expands to

json_id:
  - id: 720895714701
    name: Ted's Sub Shop - 720895714701
    templateid: '24632'
  - id: 720895714702
    name: Ted's Pizza - 720895714702
    templateid: '24663'

Then, the usage is trivial. For example

    - debug:
        msg: "{{ json_id|
                 selectattr('name', 'contains' , 'Pizza')|
                 map(attribute='id')|list }}"

gives

  msg:
  - 720895714702

The same result gives also json_query below

    - debug:
        msg: "{{ json_id|
                 json_query('[?contains(name, `Pizza`)].id') }}"
  • Related