如何使用jq根据子值对象的键对JSON对象进行分组
JSON格式转换问题
原始JSON
{"hello": [{"name": "var1","value": "1234"},{"name": "var2","value": "2356"},{"name": "var3","value": "2356"}],"hi": [{"name": "var1","value": "3412"},{"name": "var2","value": "2563"},{"name": "var3","value": "4256"}],"bye": [{"name": "var1","value": "1294"},{"name": "var2","value": "8356"},{"name": "var3","value": "5356"}]}
目标JSON
{"output": [{"var1": {"hello": "1234","hi": "3412","bye": "1294"}},{"var2": {"hello": "2356","hi": "2563","bye": "8356"}},{"var3": {"hello": "2356","hi": "4256","bye": "5356"}}]}
尝试过程及问题
使用命令:
jq 'to_entries | map(.value[]| . += {"key_v" : (.key)} )' input.json > output.json
思路是先提取顶级键并添加到子对象中,再按name分组,但执行时出现错误:cannot index array with string name or string value
解决方案
可以使用以下jq命令完成转换:
jq '{ output: to_entries | reduce .[] as $item ({}; reduce $item.value[] as $var (.; .[$var.name] += { ($item.key): $var.value } ) ) | to_entries | map({ ( .key ): .value }) }' input.json > output.json
命令逻辑拆解
to_entries:将原始JSON的顶级键值对转换为{"key": "hello", "value": [...]]}格式的数组,方便逐个处理hello/hi/bye这些顶级键。- 外层
reduce:初始化一个空对象作为累加容器,遍历每个顶级键对应的条目。 - 内层
reduce:遍历当前顶级键下的每个name-value子对象,把顶级键作为新键、子对象的value作为值,添加到累加容器中对应name的对象里。比如处理hello下的var1时,累加容器会变成{"var1": {"hello": "1234"}},后续处理hi下的var1时,会自动给var1的对象追加"hi": "3412"。 to_entries:把累加后的合并对象(如{"var1": {...}, "var2": {...}})转换为键值对数组。map({ ( .key ): .value }):将每个键值对转换为独立对象,最终组成目标要求的数组结构。
内容的提问来源于stack exchange,提问作者Evadore
相关产品推荐
相关产品推荐

