如何使用jq --stream在超大JSON数组中筛选符合条件的父级对象
流式jq筛选大文件JSON数组中符合条件的对象解决方案
报错原因
你在--stream模式下直接使用非流式的.type语法会报错,因为jq流式模式输出的不是原始JSON对象,而是[路径数组, 字段值]格式的流数据,本身是数组结构,无法用字符串键直接索引。
正确的流式处理命令
单次遍历高效方案(适合5GB大文件,仅读取一次文件)
cat file.json | jq --stream -n '[ foreach inputs as $item ( {current_idx: null, keep: false, buffer: []}; # 碰到新数组元素的边界(路径长度为1代表数组下标) if $item[0] | length == 1 then # 上一个元素符合要求就输出到结果 if .keep then .output = fromstream(1|truncate_stream(.buffer[])) | {current_idx: $item[0][0], keep: false, buffer: [], output: .output} else {current_idx: $item[0][0], keep: false, buffer: [], output: null} end else # 把当前字段加入缓冲区 .buffer += [$item] # 碰到type字段值为user就标记为需要保留 | if $item[0][1] == "type" and $item[1] == "user" then .keep = true else . end | .output = null end; # 输出符合条件的对象 select(.output != null) | .output ]'
命令说明
foreach用于边读取流边维护状态,避免将整个5GB文件加载到内存- 状态里的
keep标记当前数组元素是否符合筛选条件,buffer暂存当前元素的所有流节点 1|truncate_stream(.)用于去掉外层数组的下标路径层,fromstream将流节点重建为完整的JSON对象- 最终输出的就是你需要的包含所有type为user的对象的数组结构
内容的提问来源于stack exchange,提问作者DrTeeth
相关产品推荐
相关产品推荐

