【问题标题】:Troubles merging many large json files to even larger file将许多大型 json 文件合并到更大的文件时遇到问题
【发布时间】:2020-10-01 11:18:43
【问题描述】:

我必须在 Ubuntu 18 上将 ~1000 个大型 json 文件 (1M .. 500M) 合并为一个文件 (~80GB)。 根据this SO question,我使用 jq

 jq -s 'reduce .[] as $item ({}; . * $item)' ~/ml/train-*.json > train.json

这对于较小的文件非常有效。

发生合并的机器是一个 32 核的服务器,具有 128 GB 的 RAM。唉,任务以a结束

Killed

语句,但就内存而言,资源应该是足够的。有人可以给我一些建议如何管理这项任务吗?谢谢

【问题讨论】:

  • 你可以调用jq的流解析器来避免内存中的存储,但不要认为jq具有多处理能力来利用多核。一种方法是使用 jq 中的命令 - Cookbook - github.com/stedolan/jq/wiki/Cookbook#processing-huge-json-texts
  • 尝试jq -cn --stream ' def atomize(s): fromstream(foreach s as $in ( {previous:null, emit: null}; if ($in | length == 2) and ($in|.[0][0]) != .previous and .previous != null then {emit: [[.previous]], previous: $in|.[0][0]} else { previous: ($in|.[0][0]), emit: null} end; (.emit // empty), $in) ) ; atomize(inputs)' ~/ml/train-*.json,如果生成的文件太大而无法存储在磁盘上,请将输出通过管道传输到gzip 以进行压缩,即jq .. | gzip > result.gz,然后使用zcat 解析压缩后的文件文件

标签: json linux merge jq large-files


【解决方案1】:

在这里使用 -s 既不必要又自找麻烦。您可以尝试使用带有 -n 选项的inputs。另外我怀疑您应该使用+ 而不是*。这也应该需要更少的计算机资源:

jq -n 'reduce inputs as $item (null; . + $item)'

不过,真正的问题是您是否真的需要生成单个 JSON 实体,而不是 JSON 实体流。

jq的流解析器的相关性

jq 的流解析器(使用--stream 命令行选项调用的解析器)主要针对读取非常大的 JSON 输入,因此几乎可以肯定与所描述的问题无关。另一方面,它可能与读取生成的文件有关。

为了记录,流解析器的另一个主要用途是处理输入,其中包括带有重复键的 JSON 对象。常规 jq 解析器对此类对象使用“最右边”语义。

【讨论】:

    猜你喜欢
    • 2019-10-29
    • 1970-01-01
    • 1970-01-01
    • 2015-04-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-23
    • 1970-01-01
    • 2015-02-20
    相关资源
    最近更新 更多