arrays - JQ:删除不必要的键并重新格式化 JSON - 最有效的方法
问题描述
我有两个问题要问。这是下面的 JSON 文件。
[
{
"Header": {
"Region": "DC1"
},
"Body": [
{
"agentMetaInfoDtos": [],
"avgTraffic": 682,
"minAgentVersion": "1.191.0.20180101-000000",
"standardAgentVersion": null,
"tenantState": "ACTIVE",
"tenantUuid": "DC1-Tenant1"
},
{
"agentMetaInfoDtos": [],
"avgTraffic": 957,
"minAgentVersion": "1.185.0.20180101-000000",
"standardAgentVersion": null,
"tenantState": "DISABLED",
"tenantUuid": "DC1-Tenant2"
}
]
},
{
"Header": {
"Region": "DC2"
},
"Body": [
{
"agentMetaInfoDtos": [],
"avgTraffic": 690,
"minAgentVersion": "1.163.0.20180101-000000",
"standardAgentVersion": null,
"tenantState": "ACTIVE",
"tenantUuid": "DC2-t4-p1"
},
{
"agentMetaInfoDtos": [],
"avgTraffic": 2441,
"minAgentVersion": "1.161.0.20180101-000000",
"standardAgentVersion": null,
"tenantState": "ACTIVE",
"tenantUuid": "DC2-t5-p2"
}
]
},
{
"Header": {
"Region": "DC3"
},
"Body": [
{
"agentMetaInfoDtos": [],
"avgTraffic": 2046,
"minAgentVersion": "1.169.0.20180101-000000",
"standardAgentVersion": null,
"tenantState": "ACTIVE",
"tenantUuid": "DC3-r1-p1"
},
{
"agentMetaInfoDtos": [],
"avgTraffic": 0,
"minAgentVersion": null,
"standardAgentVersion": null,
"tenantState": "FORSAKEN",
"tenantUuid": "DC3-r2-d1"
}
]
}
]
首先,我想删除不必要的键并重新格式化 JSON。我想让结果如下所示
[
{
"Region": "DC1",
"Tenants": [
{
"tenantState": "ACTIVE",
"tenantUuid": "DC1-Tenant1"
},
{
"tenantState": "DISABLED",
"tenantUuid": "DC1-Tenant2"
}
]
},
{
"Region": "DC2",
"Tenants": [
{
"tenantState": "ACTIVE",
"tenantUuid": "DC2-t4-p1"
},
{
"tenantState": "ACTIVE",
"tenantUuid": "DC2-t5-p2"
}
]
},
{
"Region": "DC3",
"Tenants": [
{
"tenantState": "ACTIVE",
"tenantUuid": "DC3-r1-p1"
},
{
"tenantState": "FORSAKEN",
"tenantUuid": "DC3-r2-d1"
}
]
}
]
我的蛮力(假设是哑)过滤器如下 - 删除不需要的所有内容(顺便说一句,下面只是我需要删除的键的子集,还有更多):
del (.[].Body[].agentMetaInfoDtos) | del (.[].Body[].avgTraffic) | del (.[].Body[].minAgentVersion) | del (.[].Body[].standardAgentVersion) | del (.[].Body[].serverDistribution) | [.[] | {"Region": .Header.Region, Tenants:[ .Body[]] } ]
但是应该有更好的方法来做到这一点 - 只选择需要的东西而不是删除其他所有东西。顺便说一句,在该Body[]
部分中它始终是相同数量的键,它是内容agentMetaInfoDtos[]
和其他不同的数组/键。tenantState
可以有五个不同的值。
首先,尝试使用以下过滤器尝试选择正确的键,而不是删除其他所有内容:
[.[] | {Region: .Header.Region, Tenants:[ {tenantUuid: .Body[].tenantUuid, tenantState: .Body[].tenantState} ] }]
但结果是键/值的重复,如下所示。
我确信有多种方法可以实现我想要的,有人可以提供速成课程或至少指出正确的方向吗?
[
{
"Region": "DC1",
"Tenants": [
{
"tenantUuid": "DC1-Tenant1",
"tenantState": "ACTIVE"
},
{
"tenantUuid": "DC1-Tenant1",
"tenantState": "DISABLED"
},
{
"tenantUuid": "DC1-Tenant2",
"tenantState": "ACTIVE"
},
{
"tenantUuid": "DC1-Tenant2",
"tenantState": "DISABLED"
}
]
},
{
"Region": "DC2",
"Tenants": [
{
"tenantUuid": "DC2-t4-p1",
"tenantState": "ACTIVE"
},
{
"tenantUuid": "DC2-t4-p1",
"tenantState": "ACTIVE"
},
{
"tenantUuid": "DC2-t5-p2",
"tenantState": "ACTIVE"
},
{
"tenantUuid": "DC2-t5-p2",
"tenantState": "ACTIVE"
}
]
},
{
"Region": "DC3",
"Tenants": [
{
"tenantUuid": "DC3-r1-p1",
"tenantState": "ACTIVE"
},
{
"tenantUuid": "DC3-r1-p1",
"tenantState": "FORSAKEN"
},
{
"tenantUuid": "DC3-r2-d1",
"tenantState": "ACTIVE"
},
{
"tenantUuid": "DC3-r2-d1",
"tenantState": "FORSAKEN"
}
]
}
]
第二个问题 - 即使我得到了结果,之后我想进一步过滤掉它,只保留状态为 DISABLED 的条目。所以我使用了过滤器
map(select (.Tenants[].tenantState == "DISABLED" ))
,但结果显示 DC3 中的活动和禁用租户,如下所示。
有什么提示我在这里做错了吗?
[
{
"Region": "DC1",
"Tenants": [
{
"tenantState": "ACTIVE",
"tenantUuid": "DC1-Tenant1"
},
{
"tenantState": "DISABLED",
"tenantUuid": "DC1-Tenant2"
}
]
}
]
解决方案
第1部分
只需展开 .Body 一次即可轻松回答问题的第一部分:
[.[] | {Region: .Header.Region, Tenants: [.Body[] | {tenantUuid, tenantState}] }]
第2部分
为了简化这里的说明,让我们过滤上面得到的结果。如果我们想修改 .Tenants 以仅包含具有 .tenantState == "DISABLED" 的对象,我们可以将以下过滤器添加到管道中:
map( .Tenants |= map(select(.tenantState == "DISABLED")) )
然而,Q 建议应该从最终结果中排除空数组,因此我们可以进一步补充:
map( select(.Tenants != []) )
总之
综上所述:
[.[] | {Region: .Header.Region, Tenants: [.Body[] | {tenantUuid, tenantState}] }]
| map( .Tenants |= map(select(.tenantState == "DISABLED")) )
| map( select(.Tenants != []) )
当然,在管道中更早地执行选择会更有效率——无论如何,一定要这样做!
推荐阅读
- html - 是否可以使用 HTML 写入 .txt 文件?
- python - 为什么我的代码返回重复数据?
- r - 如何将正态分布曲线添加到 geom_density 中?
- javascript - 反应公共 URL 环境变量
- r - Shiny Autoreload 无法识别 App.R 中所做的更改
- asp.net-core - UserManager.GetUserAsync 总是返回 null
- python - 为数组中的每个槽分配不同的随机数
- php - 加载 MacOS php.ini 配置
- postgresql - pgadmin4 导入 CSV 文件失败退出代码 -6
- python - 从 Transfermarkt 抓取数据