如何解决大型 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-destination
、rt-entry
和 as-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 举报,一经查实,本站将立刻删除。