如何解决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","tenantState": "DISABLED","tenantUuid": "DC1-Tenant2"
}
]
},{
"Header": {
"Region": "DC2"
},"avgTraffic": 690,"minAgentVersion": "1.163.0.20180101-000000","tenantUuid": "DC2-t4-p1"
},"avgTraffic": 2441,"minAgentVersion": "1.161.0.20180101-000000","tenantUuid": "DC2-t5-p2"
}
]
},{
"Header": {
"Region": "DC3"
},"avgTraffic": 2046,"minAgentVersion": "1.169.0.20180101-000000","tenantUuid": "DC3-r1-p1"
},"avgTraffic": 0,"minAgentVersion": null,"tenantState": "FORSAKEN","tenantUuid": "DC3-r2-d1"
}
]
}
]
首先,我想删除不必要的键并重新格式化JSON。我希望结果如下所示
[
{
"Region": "DC1","Tenants": [
{
"tenantState": "ACTIVE","tenantUuid": "DC1-Tenant1"
},{
"tenantState": "DISABLED","tenantUuid": "DC1-Tenant2"
}
]
},{
"Region": "DC2","tenantUuid": "DC2-t4-p1"
},{
"tenantState": "ACTIVE","tenantUuid": "DC2-t5-p2"
}
]
},{
"Region": "DC3","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": "DISABLED"
}
]
},"Tenants": [
{
"tenantUuid": "DC2-t4-p1",{
"tenantUuid": "DC2-t4-p1",{
"tenantUuid": "DC2-t5-p2","tenantState": "ACTIVE"
}
]
},"Tenants": [
{
"tenantUuid": "DC3-r1-p1",{
"tenantUuid": "DC3-r1-p1","tenantState": "FORSAKEN"
},{
"tenantUuid": "DC3-r2-d1","tenantState": "FORSAKEN"
}
]
}
]
第二个问题-即使当我有结果时,此后我也想进一步过滤掉它,只保留状态为DISABLED的条目。所以我用了过滤器
map(select (.Tenants[].tenantState == "DISABLED" ))
,但结果显示在DC3中的活动和已禁用的租户,如下所示。
有人暗示我在做什么错吗?
[
{
"Region": "DC1","tenantUuid": "DC1-Tenant2"
}
]
}
]
解决方法
第1部分
只需扩展一次.Body即可轻松解决问题的第一部分:
[.[] | {Region: .Header.Region,Tenants: [.Body[] | {tenantUuid,tenantState}] }]
第2部分
为简化此处的说明,让我们过滤上面获得的结果。如果要修改.Tenant,使其仅包含.tenantState ==“ DISABLED”的对象,则可以在管道中添加以下过滤器:
map( .Tenants |= map(select(.tenantState == "DISABLED")) )
但是,Q建议在最终结果中排除空数组,因此我们可以进一步考虑:
map( select(.Tenants != []) )
总结
将以上内容放在一起:
[.[] | {Region: .Header.Region,tenantState}] }]
| map( .Tenants |= map(select(.tenantState == "DISABLED")) )
| map( select(.Tenants != []) )
当然,在管道中尽早执行选择会更有效率-一定要有选择!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。