当值包含ansible中的字符串时解析json值

Parse json value when value contains a string in ansible

这个 ansible 剧本有效

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

return以下

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

我需要更进一步,当 name 的值包含 Pizza 时,我需要它 return 只是最后的 12 位数字。所以 return 输出看起来像这样

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

想法?

你可以试试

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

结果:

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

添加属性可能更有效。例如下面的声明

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

扩展到

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

那么,用法就很简单了。例如

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

给予

  msg:
  - 720895714702

下面json_query也有同样的结果

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