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

使用jq处理50GB超大JSON文件时内存耗尽的问题排查与解决

解决大JSON文件内存耗尽问题:提取data数组元素逐行输出

你的问题核心在于第一个jq命令会把整个data数组重新构建成完整的JSON对象后再传递给第二个jq,这直接导致50GB的文件被全部加载到内存中,自然触发内存耗尽。咱们来拆解问题,给出高效的流处理方案:

为什么原命令会失效?

先看你的原命令:

jq -cn --stream 'fromstream(1|truncate_stream(inputs))' file.json | jq -cr .data[] >> out.json
  • 1|truncate_stream(inputs) 会去掉所有流数据的路径第一层(也就是移除"data"前缀),随后fromstream会把这些零散的流数据重新组装成完整的data数组对象——这一步完全违背了--stream的设计初衷,它会把整个数组加载到内存里,直接引发内存溢出。
  • 后续管道到第二个jq提取.data[]时,第一个jq已经把庞大数据读进内存,崩溃是必然的。

正确的流处理命令

我们可以直接在流模式下筛选并输出data数组的每个元素,不需要先构建整个数组。用下面的单步命令即可:

jq -cn --stream '
  fromstream(
    inputs
    | select(.[0][0] == "data" and (.[0] | length) == 2)
    | .[0] |= .[1:]
  )' file.json >> out.json

命令逐段解释:

  1. --stream:开启流处理模式,逐块读取JSON,全程不会把整个文件加载到内存
  2. inputs:获取所有流输入(每个输入是[路径, 值]的数组,比如[["data",0,"id"], "id1"])
  3. select(.[0][0] == "data" and (.[0] | length) == 2):只保留路径第一层是"data"且路径长度为2的流数据——这对应的是data数组里的单个完整元素(比如路径["data",0]对应整个{"id":"id1","value":"value1"}对象的所有流片段)
  4. .[0] |= .[1:]:把路径从["data",0]修改为[0],让fromstream能正确把这些流片段重建为单个独立对象
  5. -c:以紧凑格式输出每个对象,正好满足你逐行输出的需求

这个命令会逐个处理data数组里的元素,处理完一个就输出一个,内存占用始终维持在极低水平,完全不会出现内存耗尽的问题。

额外优化点

原命令用两个jq进程通过管道传递数据,会产生额外的IO开销。上面的单进程命令直接完成所有操作,效率更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 20:47:31