gpt4 book ai didi

json - (已解决)如何用jq读取100+GB的文件而不耗尽内存

转载 作者:行者123 更新时间:2023-12-03 08:01:18 25 4
gpt4 key购买 nike

我有一个 100+GB 的 json 文件,当我尝试用 jq 读取它时,我的计算机继续运行我们的 ram。有没有办法在限制内存使用的同时读取文件,或者有其他方法来读取非常大的 json 文件?

我在命令中输入的内容:jq 'keys' fileName.json

最佳答案

确定包含单个 JSON 实体的非常大文件的结构的一种通用方法是运行以下查询:

jq -nc --stream -f structural-paths.jq huge.json | sort -u

其中structural_paths.jq包含:

inputs
| select(length == 2)
| .[0]
| map( if type == "number" then 0 else . end )

请注意,输出中的“0”表示相应位置至少有一个有效的数组索引,而不是“0”实际上是该位置的有效索引。

另请注意,对于非常大的文件,使用 jq --stream 处理整个文件可能会非常慢。

示例:

给定 {"a": {"b": [0,1, {"c":2}]}},上述咒语的结果将是:

["a","b",0,"c"]
["a","b",0]

顶层结构

如果您只是想了解有关顶层结构的更多信息,您可以将上面的 jq 程序简化为:

inputs | select(length==1)[0][0] | if type == "number" then 0 else . end

给定深度的结构

如果命令行sort失败,那么您可能希望通过仅将路径考虑到一定深度来限制路径数量。

如果深度不是太大,那么希望您的命令行 sort 能够管理;如果没有,那么使用命令行 uniq 至少会稍微修剪输出。

更好的选择可能是在 jq 中定义 unique(stream),然后使用它,如下所示:

# Output: a stream of the distinct `tostring` values of the items in the stream
def uniques(stream):
foreach (stream|tostring) as $s ({};
if .[$s] then .emit = false else .emit = true | .item = $s | .[$s]=true end;
if .emit then .item else empty end );

def spaths($depth):
inputs
| select(length==1)[0][0:$depth]
| map(if type == "number" then 0 else . end);

uniques(spaths($depth))

jq 的合适调用如下所示:

jq -nr --argjson depth 3 --stream -f structural-paths.jq huge.json

除了避免排序成本之外,使用 uniques/1 还将保留原始 JSON 中路径的顺序。

“JSON 指针”指针

如果您想将数组路径表达式转换为“JSON Pointer”字符串(例如与 jmjstream 一起使用),只需将以下内容附加到相关的 jq 程序即可:

| "/" + join("/")

关于json - (已解决)如何用jq读取100+GB的文件而不耗尽内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74076187/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com