在Ansible中访问JSON格式列表的每个键的值

问题描述

我有以下列表,这些列表是我在cisco控制器的json_query的帮助下查询的。

"aci_access_port_list": [
            [
                {
                    "description": [
                        "NOMON KASTOM"
                    ],"port_name": "E1-17"
                },{
                    "description": [
                        "ASDF NOMON K"
                    ],"port_name": "E1-16"
                },{
                    "description": [
                        "NOMON K9876"
                    ],"port_name": "E1-15"
                },{
                    "description": [
                        "LAN5002 TC "
                    ],"port_name": "E1-46"
                },"port_name": "E1-47"
                },{
                    "description": [
                        "NOMON LAN5001 TC "
                    ],"port_name": "E1-45"
                },{
                    "description": [
                        "LAN5001 TC "
                    ],"port_name": "E1-48"
                },{
                    "description": [
                        "NOMON No Cabling - TEST-4-AUTOMATION"
                    ],"port_name": "E1-30"
                },{
                    "description": [
                        "NOMON No Cabling - TEST-6-AUTOMATION"
                    ],"port_name": "E1-31"
                }
            ]
        ]

我要检查每个description键,如果它写有“ NOMON K ”,则将其保存到新列表中。为此,我写了以下内容

- set_fact:
    clean_list: [\n]
- name: getting the clean list of ports and descr.
  set_fact:
    clean_list: "{{clean_list }} \n {{item.0.port_name}} - {{item.1}}"
  loop: "{{ aci_access_port_list[0]|subelements('description') }}"
  when: item.1 is search ("NOMON K")

- debug:
    msg: "{{ clean_list }}"

这将返回:

ok: [acitst-apic.net.dsh.at] => {
    "msg": "[u'\\\\n'] \n E1-17 - NOMON KASTOM \n E1-16 - ASDF NOMON K \n E1-15 - NOMON K9876"
}

我想要的格式与 aci_access_port_lists相同,但是我无法弄清楚。看起来应该像这样:

"clean_list":[
                {
                    "description": [
                        "NOMON KASTOM"
                    ],"port_name": "E1-15"
                }
             ]

我认为有更好的方法,但是我找不到,如果有人可以帮助我,我会很高兴。预先谢谢你。

解决方法

使用selectattr过滤器和contains测试将description列表的第一个元素作为目标是可行的,因为它始终只有一个元素。当然,如果您在该列表中有多个元素,这种方法将会失效。

    - name: Show me a clean list
      vars:                                                                                                  
        clean_list: >-
          {{
            aci_access_port_list.0 |
            selectattr('description.0','contains','NOMON K') |
            list
          }}
      debug:
        var: clean_list