Michael
Michael

Reputation: 237

How parse a list of dictionary and out the values in Ansible?

I've the following json output. It is a list of dictionary. I just want to parse it and output its value.

I've tried the following play but without success...

"output1": {
    "changed": false, 
    "msg": "All items completed", 
    "results": [
        {
            "item": [
                {
                    "Device_Name": "SW1"
                }, 
                {
                    "Interface": "GigabitEthernet1/0/7"
                }
                    ]
         }
    ]
}
    - name: Display output1...2
      debug:
        msg: "{{ item.1.Device_Name }};{{ item.1.Interface }}"
      with_subelements: 
        - "{{ output1.results }}"
        - item

The error was ""msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'int_name'\n\n"

Upvotes: 1

Views: 5530

Answers (2)

Vladimir Botka
Vladimir Botka

Reputation: 67984

Quick and dirty

The tasks below give quickly what is requested

- set_fact:
    Device_Name: "{{ output1.results[0]['item']|
                     map(attribute='Device_Name')|
                     select('defined')|
                     list|first }}"
    Interface: "{{   output1.results[0]['item']|
                     map(attribute='Interface')|
                     select('defined')|
                     list|first }}"

Details

This is a typical example of bad data structure. The task below

- debug:
    msg: "{{ output1.results|
             map('dict2items')|list|flatten|
             json_query('[?key==`item`].value')|flatten }}"

gives item, which is a list and must be iterated again,

"msg": [
        {
            "Device_Name": "SW1"
        }, 
        {
            "Interface": "GigabitEthernet1/0/7"
        }
]

instead of a dictionary, which could be easily referenced.

"msg": [
        {
            "Device_Name": "SW1",
            "Interface": "GigabitEthernet1/0/7"
        }
]

As a result of such filtering the tasks below

- set_fact:
    Device_Name: "{{ output1.results|
                     map('dict2items')|list|flatten|
                     json_query('[?key==`item`].value')|flatten|
                     map('dict2items')|list|
                     json_query('[*][?key==`Device_Name`].value')|flatten }}"
- set_fact:
    Interface: "{{ output1.results|
                   map('dict2items')|list|flatten|
                   json_query('[?key==`item`].value')|flatten|
                   map('dict2items')|list|
                   json_query('[*][?key==`Interface`].value')|flatten }}"
- debug:
    var: Device_Name
- debug:
    var: Interface

give

"Device_Name": [
    "SW1"
]

"Interface": [
    "GigabitEthernet1/0/7"
]

Upvotes: 0

Prakash Krishna
Prakash Krishna

Reputation: 1257

Try below - I have not tested it though.

    - name: Display output1...2
      debug:
        msg: "{{ item|first }} : {{ item[item|first] }}"
      with_items:
        - "{{ output1.results[0].item }}"

Upvotes: 3

Related Questions