如何按表键名执行group_by?解决jq分组报错及数据处理问题
jq分组JSON数据问题解决方案
问题背景
有一组拆分后的JSON对象:
{ "london": [ "x", 0 ] } { "london": [ "y", 97 ] } { "paris": [ "x", 15 ] } { "paris": [ "y", 8 ] }
需要按城市键分组,期望两种合法JSON输出格式之一:
格式1(城市对应子数组的数组)
{ "london": [["x", 0], ["y", 97]], "paris": [["x", 15], ["y", 8]] }
格式2(城市对应键值对象的数组)
{ "london": [{"x": 0}, {"y": 97}], "paris": [{"x": 15}, {"y": 8}] }
执行以下jq命令时触发错误:
jq -s 'group_by(keys_unsorted[0]) | map({(.[0]): map(.[1])})'
错误信息:
jq: error (at :4): Cannot index object with number
同时提供了原始数据源,期望直接从原始数据生成目标结果,最初尝试的命令未达预期:
jq -c '.city as $j | foreach .zoo[] as $i (.; .; {($j): [$i.room.name, $i.gpu.sum]})'
原始数据源:
{ "city": "london", "zoo": [ { "room": { "name": "x" }, "gpu": { "id": "fish", "sum": 0 } }, { "room": { "name": "y" }, "gpu": { "id": "zebra", "sum": 97 } } ] } { "city": "paris", "zoo": [ { "room": { "name": "x" }, "gpu": { "id": "fish", "sum": 15 } }, { "room": { "name": "y" }, "gpu": { "id": "zebra", "sum": 8 } } ] }
错误原因
原命令中map(.[1])试图用数字索引JSON对象,而分组后的每个元素是完整的键值对象(如{"london": ["x",0]}),并非数组,因此无法通过数字索引访问内容,导致报错。
解决方案
1. 处理拆分后的中间JSON数据
生成格式1
jq -s 'reduce .[] as $obj ({}; $obj | keys_unsorted[0] as $k | .[$k] += [ $obj[$k] ] )'
生成格式2
jq -s 'reduce .[] as $obj ({}; $obj | keys_unsorted[0] as $k | .[$k] += [ {($obj[$k][0]): $obj[$k][1]} ] )'
2. 直接处理原始数据源(更高效)
无需先拆分数据,一步生成目标格式:
生成格式1
jq -s 'reduce .[] as $city ({}; .[$city.city] += ($city.zoo | map([.room.name, .gpu.sum])) )'
生成格式2
jq -s 'reduce .[] as $city ({}; .[$city.city] += ($city.zoo | map({(.room.name): .gpu.sum})) )'
内容的提问来源于stack exchange,提问作者Udi
相关产品推荐
相关产品推荐

