首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在json查询中跳过空值?

如何在json查询中跳过空值?
EN

Stack Overflow用户
提问于 2022-04-21 00:28:48
回答 2查看 272关注 0票数 2

我试图从json文件中提取值,但我不想要空值吗?如何轻松跳过null值?

我只是试图找到将JSON解析为YALM的最简单和最简单的解决方案,并且在YAML中没有格式错误。也许我已经把事情复杂化了。

杰森:

代码语言:javascript
复制
{
    "configuration": {
       "protocols" : {
            "bgp" : {
                "group" : [
                {
                    "name" : "IBGP",
                    "neighbor" : [
                    {
                        "name" : "192.168.1.2",
                        "description" : "router-2"
                    }
                    ]
                },
                {
                    "name" : "EBGP",
                    "neighbor" : [
                    {
                        "name" : "192.168.2.2",
                        "description" : "router-3",
                        "local-address" : "192.168.2.1",
                        "peer-as" : "65555"
                    }
                    ]
                }
            ]
            }
        }
    }
}

演奏:

代码语言:javascript
复制
- name: parse bgp
  set_fact:
    bgp: "{{ read | to_json | from_json | json_query(bgp_var) }}"
  vars:
    bgp_var: 'configuration.protocols.bgp.group[].{group_name:name,neighbors:[{peer_ip:neighbor[].name | [0], peer_description:neighbor[].description | [0], peer_as:neighbor[]."peer-as" | [0] }]}'

- copy:
    content: >-
      routing_protocols:
        bgp:
          {{ bgp | to_nice_yaml(indent=2, width=1337, sort_keys=False) | indent(4) }}  
    dest: "{{ inventory_hostname }}_routing_protocols.yaml"

返回:

代码语言:javascript
复制
routing_protocols:
  bgp:
    - group_name: IBGP
      neighbors:
      - peer_as: null # < Is there a way to skip this anytime a value is null?
        peer_description: router-2
        peer_ip: 192.168.1.2

    - group_name: EBGP
      neighbors:
      - peer_as: '65555'
        peer_description: router-3
        peer_ip: 192.168.2.2
EN

回答 2

Stack Overflow用户

发布于 2022-04-21 08:31:04

您可以使用此剧本中省略的参数:

代码语言:javascript
复制
  tasks:
    - name: set var
      set_fact:
        bgp: >-
          {{ bgp | d([]) + 
            [ {'group_name': _gpname, 
               'neighbors': [{'peer_description': _desc, 'peer_ip': _peerip, 'peer_as': _peeras}]
              }
            ] }}      
      loop: "{{ configuration.protocols.bgp.group }}"
      vars:
        _gpname: "{{ item.name }}"
        _desc: "{{ item.neighbor.0.description }}"
        _peeras: "{{ item.neighbor[0]['peer-as'] | d(omit)}}"
        _peerip: "{{ item.neighbor.0.name }}"
    - name: displ
      debug:
        msg: "{{ bgp }}"

结果:

代码语言:javascript
复制
ok: [localhost] => {
    "msg": [
        {
            "group_name": "IBGP",
            "neighbors": [
                {
                    "peer_description": "router-2",
                    "peer_ip": "192.168.1.2"
                }
            ]
        },
        {
            "group_name": "EBGP",
            "neighbors": [
                {
                    "peer_as": "65555",
                    "peer_description": "router-3",
                    "peer_ip": "192.168.2.2"
                }
            ]
        }
    ]
}
票数 1
EN

Stack Overflow用户

发布于 2022-04-21 23:05:59

您可以在JMESPath中一次执行,但这需要对属性neighbour进行双重查询,因为JMESPath不能像Ansible can那样省略属性(有关这一点,请参阅@Frenchy的回答)。

因此,您必须有一个列表列表,其中,第一个子列表由包含键peer-aspeer-as和不包含它的第二个子列表组成。然后,您必须压扁这个列表的列表。

因此,下面是copy任务:

代码语言:javascript
复制
- copy:  
  content: >-
      {{
        read
        | to_json
        | from_json
        | json_query(query)
        | to_nice_yaml(indent=2)
      }}
    dest: "{{ inventory_hostname }}_routing_protocols.yaml"
  vars:
    query: >-
      {
        routing_protocols: {
          bgp: configuration.protocols.bgp.group[].{
            group_name: name,
            neighbors: [
              neighbor[?"peer-as"].{
                peer_description: description,
                peer_ip: name,
                peer_as: "peer-as"
              },
              neighbor[?"peer-as" == null].{
                peer_description: description,
                peer_ip: name
              }
            ]|[]
          }
        }
      }

在完成此任务后,您将以一个YAML文件结束,该文件包含您期望的:

代码语言:javascript
复制
routing_protocols:
  bgp:
  - group_name: IBGP
    neighbors:
    - peer_description: router-2
      peer_ip: 192.168.1.2
  - group_name: EBGP
    neighbors:
    - peer_as: '65555'
      peer_description: router-3
      peer_ip: 192.168.2.2
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71947608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档