json - 使用 jq 展开具有可能空值的嵌套 JSON 对象?
问题描述
我有一个包含 3 个项目的 json 响应,如下所示:
{
"id": 44,
"extra": [{
"domain": {
"id": 3,
"name": "person"
},
"entity": {
"label": "Noon",
"serial": 8938493
}
},
{
"domain": {
"id": 4,
"name": "place"
},
"entity": {
"label": "Rad",
"serial": 8932321
}
}]
}
{
"id": 45,
"extra": null
}
{
"id": 46,
"extra": [{
"domain": {
"id": 90,
"name": "animal"
},
"entity": {
"label": "Foo",
"serial": 892121
}
},
{
"domain": {
"id": 91
},
"entity": {
"label": "Ear",
"serial": 823414
}
},
{
"domain": {
"id": 92
},
"entity": {
"label": "Owl",
"serial": 889232
}
}]
}
我的目标是将此响应转化为:
{
"id": 44,
"extra_domain_id": 3,
"extra_domain_name": "person",
"extra_entity_label": "Noon",
"extra_entity_serial": 8938493
},
{
"id": 44,
"extra_domain_id": 4,
"extra_domain_name": "place",
"extra_entity_label": "Rad",
"extra_entity_serial": 8932321
},
{
"id": 45,
"extra_domain_id": null,
"extra_domain_name": null,
"extra_entity_label": null,
"extra_entity_serial": null
},
{
"id": 46,
"extra_domain_id": 90,
"extra_domain_name": "animal",
"extra_entity_label": "Foo",
"extra_entity_serial": 892121
},
{
"id": 46,
"extra_domain_id": 91,
"extra_domain_name": null,
"extra_entity_label": "Ear",
"extra_entity_serial": 823414
},
{
"id": 46,
"extra_domain_id": 92,
"extra_domain_name": null,
"extra_entity_label": "Owl",
"extra_entity_serial": 889232
}
请注意,在数组的最后两个条目 91 和 92 中缺少id
46的第三项,因此它们被替换为 null。
这是我尝试过的domain.name
extra
{"id": .id, "extra_domain_id": .extra[].domain.id, "extra_domain_name": .extra[].domain.name, "extra_entity_label": .extra[].entity.label, "extra_entity_serial": .extra[].entity.serial}
但它没有给我想要的输出,它返回响应中每个项目中所有可能组合的笛卡尔积!
解决方案
暂时忽略所示的预期输出不是严格意义上的有效 JSON,一种可能的解决方案是使用如下调用:
jq -nf program.jq input.json
其中 program.jq 包含:
[inputs
| {id} +
((.extra[]? // {})
| {"extra_domain_id": .domain.id,
"extra_domain_name": .domain.name,
"extra_entity_label": .entity.label,
"extra_entity_serial": .entity.serial} ) ]
这将生成一个包含所需对象的数组。如果您希望生成 Q 中所示的无效 JSON,请随意使用您遇到的任何不正当手段,例如去掉前导方括号和尾随方括号。
笔记
{"id": .id}
可以缩写,如图。- 请注意如何通过仅指定一次项来避免组合爆炸。
- 后缀“?” 在表达式
E?
中具有以下效果try E catch empty
- 处理的
empty
情况下,//
一直使用。 - 如果您想要一个有效的 JSON 对象流作为输出,您可以通过删除
-n
选项和使用inputs
将所有内容包装到数组中来简化一些事情。
推荐阅读
- groovy - 如何在 Nifi 中比较两个 CSV 文件?
- sql - 检索由未响应 to_sql 的 active_record 方法执行的原始 SQL
- java - jersey 2.22 中的 servicelocator impl 关闭问题
- nginx - 位置将所有 /*.xml 重定向到 /*
- javascript - 反应应用程序中的套接字io多个连接
- firebase - 我可以让`firebase deploy`在开始上传之前先运行`yarn build`吗?
- reactjs - 如何通过反应发送 x-www-form-urlencoded 请求?
- javascript - 我已经从 html 创建了 pdf 现在我想将此 pdf 上传到 cloudinary 或我们的服务器而不将其保存到客户端 PC
- java - 阅读器不会为某些 epub 文件复制 css,我该如何解决这个问题?
- maven - 使用基于詹金斯的战争时,春季启动启动失败