微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

大型 JSON 文件上的 JMESPath 过滤器/多选

如何解决大型 JSON 文件上的 JMESPath 过滤器/多选

数据源是以 json 格式输出的瞻博网络路由器路由表(> 3 GB json 文件)。我最终想要的是能够遍历前缀列表并获得前缀作为路径组合。

#!/usr/bin/env python

import json
from jmespath import search

jsonData = """{
  "route-information": [
    {
      "route-table": [
        {
          "rt": [
            {
              "rt-destination": [
                {
                  "data": "2001:db8:1::/48"
                }
              ],"rt-entry": [
                {
                  "as-path": [
                    {
                      "data": "64511 65551 I"
                    }
                  ]
                }
              ]
            },{
              "rt-destination": [
                {
                  "data": "2001:db8:2::/48"
                }
              ],"rt-entry": [
                {
                  "as-path": [
                    {
                      "data": "65536 64496 I"
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}"""

data = json.loads(jsonData)

query='"route-information"[]."route-table"[].rt[].{\"destination\": \"rt-destination\",path: \"rt-entry\"}'

output = search(query,data)
print(output)

上面的 query 结果:

[{'destination': [{'data': '2001:db8:1::/48'}],'path': [{'as-path': [{'data': '64511 65551 I'}]}]},{'destination': [{'data': '2001:db8:2::/48'}],'path': [{'as-path': [{'data': '65536 64496 I'}]}]}]

看起来是正确的方式。但是我想要 prefix : as-path 组合,所以我想去掉“data:”和“as-path.data”部分(在实际的 json 文件中,此级别上还有更多对象,我尝试在此处删除它们)。

query='"route-information"[]."route-table"[].rt[].{\"destination\": \"rt-destination\",path: \"rt-entry\".\"as-path\"}

和/或

query='"route-information"[]."route-table"[].rt[].{\"destination\": \"rt-destination\",path: \"rt-entry\".\"as-path\".data}'

结果:

[{'destination': [{'data': '2001:db8:1::/48'}],'path': None},'path': None}]

任何想法为什么“无”和/或/如何继续?

一个想法是过滤:

query='"route-information"[]."route-table"[].rt[?"rt-destination".data==`2001:db8:2::/48`]'

然后进一步向下工作以获得 as-path。但查询结果为 [[]] where as

query='"route-information"[]."route-table"[].rt[?"rt-destination".data=="2001:db8:2::/48"]'

导致

[[{'rt-destination': [{'data': '2001:db8:1::/48'}],'rt-entry': [{'as-path': [{'data': '64511 65551 I'}]}]},{'rt-destination': [{'data': '2001:db8:2::/48'}],'rt-entry': [{'as-path': [{'data': '65536 64496 I'}]}]}]]

所以根本没有过滤。

解决方法

如果您的目标是获得一组如下所示的数据:

[
  {
    "destination":  "2001:db8:1::/48","path": "64511 65551 I"
  },{
    "destination": "2001:db8:2::/48","path": "65536 64496 I"
  }
]

可以简单地通过这个查询来实现:

route-information[].route-table[].rt[].{destination: rt-destination[0].data,path: rt-entry[0].as-path[0].data}

但我怀疑,根据您在 rt-destinationrt-entryas-path 下的列表,此查询实际上可能会让您错过一些数据。

这是一种不太可能让您错过数据的方法,但它在 path 下创建了一个列表,因此生成的 JSON 如下所示:

[
  {
    "destination": [
      "2001:db8:1::/48"
    ],"path": [
      "64511 65551 I"
    ]
  },{
    "destination": [
      "2001:db8:2::/48"
    ],"path": [
      "65536 64496 I"
    ]
  }
]

查询是:

route-information[].route-table[].rt[].{destination: rt-destination[*].data,path: rt-entry[*].as-path[*].data | [] }

此查询使用展平运算符 |,这在 working with nested data 下的示例中进行了说明。


这是一个演示此的脚本:

import jmespath

data = {
  "route-information": [
    {
      "route-table": [
        {
          "rt": [
            {
              "rt-destination": [
                {
                  "data": "2001:db8:1::/48"
                }
              ],"rt-entry": [
                {
                  "as-path": [
                    {
                      "data": "64511 65551 I"
                    }
                  ]
                }
              ]
            },{
              "rt-destination": [
                {
                  "data": "2001:db8:2::/48"
                }
              ],"rt-entry": [
                {
                  "as-path": [
                    {
                      "data": "65536 64496 I"
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

query = [
    '"route-information"[]."route-table"[].rt[].{destination: "rt-destination"[0].data,path: "rt-entry"[0]."as-path"[0].data}','"route-information"[]."route-table"[].rt[].{destination: "rt-destination"[*].data,path: "rt-entry"[*]."as-path"[*].data | [] }'
]

print(jmespath.search(query[0],data))
print('---------------------------')
print(jmespath.search(query[1],data))

印刷品(手工美化):

[
   {
      "destination":"2001:db8:1::/48","path":"64511 65551 I"
   },{
      "destination":"2001:db8:2::/48","path":"65536 64496 I"
   }
]
---------------------------
[
   {
      "destination":[
         "2001:db8:1::/48"
      ],"path":[
         "64511 65551 I"
      ]
   },{
      "destination":[
         "2001:db8:2::/48"
      ],"path":[
         "65536 64496 I"
      ]
   }
]

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。