[英]Flatten a JSON document using jq
我正在考虑以下 JSON 对象数组:
[
{
"index": "index1",
"type": "type1",
"id": "id1",
"fields": {
"deviceOs": [
"Android"
],
"deviceID": [
"deviceID1"
],
"type": [
"type"
],
"country": [
"DE"
]
}
},
{
"index": "index2",
"type": "type2",
"id": "id2",
"fields": {
"deviceOs": [
"Android"
],
"deviceID": [
"deviceID2"
],
"type": [
"type"
],
"country": [
"US"
]
}
}
]
我想将其展平以获得:
[
{
"index": "index1",
"type": "type",
"id": "id1",
"deviceOs": "Android",
"deviceID": "deviceID1",
"country": "DE"
},
{
"index": "index2",
"type": "type",
"id": "id2",
"deviceOs": "Android",
"deviceID": "deviceID2",
"country": "US"
}
]
我正在尝试与jq
合作,但我无法展平"fields"
。 我应该怎么做? 目前我对命令行工具很感兴趣,但我也愿意接受其他建议。
这个是一个棘手的工艺。
map
(
with_entries(select(.key != "fields"))
+
(.fields | with_entries(.value = .value[0]))
)
让我们分解并解释它的各个部分
对于阵列中的每个项目......
map(...)
创建一个新对象,其中包含除fields
属性之外的所有值。
with_entries(select(.key != "fields"))
结合......
+
每个fields
每个值投影到每个数组的第一项
(.fields | with_entries(.value = .value[0]))
您可以使用此过滤器:
[.[] | {index: .index, type: .type, id: .id, deviceOs: .fields.deviceOs[],deviceID: .fields.deviceID[],country: .fields.country[]}]
你可以在这里测试https://jqplay.org
下面是一些变体,首先将.fields合并到包含对象中,然后展开数组元素。 首先我们照顾.fields
.[]
| . + .fields
| del(.fields)
这让我们看起来像是一样的物体
{
"index": "index1",
"type": [
"type"
],
"id": "id1",
"deviceOs": [
"Android"
],
"deviceID": [
"deviceID1"
],
"country": [
"DE"
]
}
然后我们可以多种方式压扁键。 一种方法是使用with_entries
| with_entries( .value = if .value|type == "array" then .value[0] else .value end )
另一种方法是使用reduce和setpath
| . as $v
| reduce keys[] as $k (
{};
setpath([$k]; if $v[$k]|type != "array" then $v[$k] else $v[$k][0] end)
)
有一个名为gron
的工具,你可以管道json,以获得这样的东西。
$ gron document.json
json = [];
json[0] = {};
json[0].fields = {};
json[0].fields.country = [];
json[0].fields.country[0] = "DE";
json[0].fields.deviceID = [];
json[0].fields.deviceID[0] = "deviceID1";
json[0].fields.deviceOs = [];
json[0].fields.deviceOs[0] = "Android";
json[0].fields.type = [];
json[0].fields.type[0] = "type";
json[0].id = "id1";
json[0].index = "index1";
json[0].type = "type1";
json[1] = {};
json[1].fields = {};
json[1].fields.country = [];
json[1].fields.country[0] = "US";
json[1].fields.deviceID = [];
json[1].fields.deviceID[0] = "deviceID2";
json[1].fields.deviceOs = [];
json[1].fields.deviceOs[0] = "Android";
json[1].fields.type = [];
json[1].fields.type[0] = "type";
json[1].id = "id2";
json[1].index = "index2";
json[1].type = "type2";
类似于@jq170727 anwser:
jq 'map(. + (.fields | with_entries(.value |= .[])) | del(.fields))'
(假设.fields
中没有字段本身称为.fields
)。
|with_entries(.value|=.[])
部分是将 .fields 中的值.fields
展平——注意只保留第一项。 .value|=join(", ")
可用于将多个字符串值合并为一个。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.