如何使用jq流将JSON数组按指定键转换为对象?
大JSON数组流式转索引对象的解决方案
你的问题出在原命令先把流还原成完整数组再执行INDEX,本质和非流处理一样,会加载整个大文件到内存,自然报错。要真正用流处理实现和jq 'INDEX(.id)'相同的结果,需要在流遍历过程中直接构建索引对象,不用还原整个数组。
正确的流式处理命令
jq -n --stream ' reduce inputs as $item ({}; if $item[0][0] == null then . else ($item[0] | .[1:]) as $path | ($item[1] | if $item[0][-1] == "id" then . else null end) as $id | if $id != null then .[$id] = {} else . end | setpath($path; $item[1]) end )' test.json > result.json
命令逻辑说明
- 用
reduce遍历流中的每一条路径-值对,初始结果为空对象 - 流中
$item的格式为[路径数组, 值],比如数组第一个元素的id对应[[0, "id"], 1] - 跳过数组结束的标记(路径第一个元素为
null时) - 提取元素内部的路径(去掉最外层的数组索引,比如
[0, "name"]转为["name"]) - 当当前路径指向
id字段时,在结果对象中初始化对应键的空对象 - 用
setpath将当前值写入结果对象的对应位置
这样处理全程不会加载完整数组到内存,完美适配大JSON文件,最终输出结果和jq 'INDEX(.id)'完全一致。
内容的提问来源于stack exchange,提问作者wojteklu
相关产品推荐
相关产品推荐

