如何使用jq读取100+GB超大JSON文件且避免内存耗尽
处理超大型JSON文件的内存友好方案
1. 用jq的流式处理模式(--stream参数)
jq默认会把整个JSON文件加载到内存,这是导致大文件内存耗尽的核心原因。使用--stream参数可以让jq以流式方式处理数据,仅加载当前处理的片段:
jq --stream 'select(.[0] | length == 1) | .[0][0]' fileName.json | uniq
--stream将JSON拆分为[路径数组, 值]的流格式select(.[0] | length == 1)筛选出顶级键对应的路径(路径数组长度为1)uniq用于去重,因为流式处理会重复输出同一个键的多条记录
如果目标JSON是大型数组,要提取数组元素的键,调整筛选条件即可:
jq --stream 'select(.[0] | length == 2) | .[0][1]' fileName.json | uniq
2. 使用专门的大型JSON处理工具
- ijq:交互式jq变体,原生支持流式处理,内存占用极低,可直接用jq语法查询,无需加载整个文件
- Python json模块流式解析:通过脚本逐块处理JSON,避免全量加载:
import json from collections import defaultdict seen_keys = set() with open('fileName.json', 'r') as f: decoder = json.JSONDecoder() buffer = '' for chunk in f: buffer += chunk while True: try: obj, idx = decoder.raw_decode(buffer) buffer = buffer[idx:] if isinstance(obj, dict): for key in obj.keys(): if key not in seen_keys: seen_keys.add(key) print(key) except ValueError: break
3. 预处理拆分JSON(结构允许时)
如果JSON是每行一个独立对象的NDJSON格式,可直接用轻量工具提取键:
awk -F'"' '/":/ {print $2}' fileName.json | uniq
若是单一大型对象/数组,可使用专门的JSON拆分工具(如jq-split)将文件拆分为可解析的小块后分别处理,避免一次性加载全量数据。
内容的提问来源于stack exchange,提问作者KTK
相关产品推荐
相关产品推荐

