4

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?

2
  • => ... | map(attribute='name) | map('regex_replace', '^.*(\\d*)$', '\\1') Commented Apr 28, 2022 at 17:30
  • This works! I had to make on slight change. The place I was really using this expected a jinja statement so no need for the {{ }}. Because of this it appears \d and \1 did not need the extra \. Meaning they only needed a singe \ not a \\ in front of them. Not sure why (assuming I will eventually come across an answer)....but for now I am up and running!!! Commented Apr 28, 2022 at 21:14

2 Answers 2

2

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"
    ]
}
Sign up to request clarification or add additional context in comments.

1 Comment

I had been looking for a contains operator but never found one. Glad you shared this. Works like a charm now.
1

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') }}"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.