You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用jq的--streaming模式展开超大JSON文件中的文档?

用jq流式处理超大JSON数组展开需求

给定超大JSON文件,结构如下:

[
  { "a": 4, "b": [1,2,3] },
  { "a": 6, "b": [7,8,9] }
]

需要转换为:

{ "a": 4, "b": 1 },
{ "a": 4, "b": 2 },
{ "a": 4, "b": 3 },
{ "a": 6, "b": 7 },
{ "a": 6, "b": 8 },
{ "a": 6, "b": 9 }

小文件可以用.[] | {a: .a, b: .b[]}处理,但超大文件需要启用--stream模式避免内存溢出,以下是实现方法。


流式处理的jq过滤器

流式模式下,jq会将JSON拆解为[路径, 值]的条目序列,我们需要通过维护状态来关联每个对象的a值和其b数组中的元素。

过滤器代码(保存为filter.jq)

reduce inputs as $i (
  { current_a: null, index: null };
  if $i[0][-1] == "a" then
    { current_a: $i[1], index: $i[0][0] }
  elif $i[0][-2] == "b" and $i[0][0] == .index then
    ( {a: .current_a, b: $i[1] } ) , .
  else
    .
)
| select(type == "object")

执行命令

jq --stream -n -f filter.jq your_large_file.json

或者直接在命令行使用单行过滤器:

jq --stream -n 'reduce inputs as $i ( { current_a: null, index: null }; if $i[0][-1] == "a" then { current_a: $i[1], index: $i[0][0] } elif $i[0][-2] == "b" and $i[0][0] == .index then ( {a: .current_a, b: $i[1] } ) , . else . end ) | select(type == "object")' your_large_file.json

工作原理

  1. 状态维护:使用reduce跟踪两个状态变量:current_a(当前对象的a值)和index(当前处理的数组元素索引)。
  2. 捕获a值:当遇到路径末尾为"a"的条目时,更新状态,记录该对象的索引和a值。
  3. 生成结果:当遇到路径倒数第二位为"b"且索引匹配当前状态的条目时,结合current_a生成目标对象并输出。
  4. 过滤输出:最后过滤掉状态对象,只保留生成的目标JSON对象。

关键参数说明

  • --stream:启用流式处理,逐块读取JSON,不加载整个文件到内存。
  • -n:禁用默认读取标准输入为JSON的行为,改用inputs获取流式条目。

内容的提问来源于stack exchange,提问作者Ztyx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 13:06:28