gpt4 book ai didi

json - Bash循环为mongoimport批量合并文件

转载 作者:可可西里 更新时间:2023-11-01 09:39:17 25 4
gpt4 key购买 nike

我有一个包含 250 万个小 JSON 文件的目录。磁盘上有 104gb。它们是多行文件。

我想从这些文件创建一组 JSON 数组,以便我可以在合理的时间内使用 mongoimport 导入它们。这些文件不能超过 16mb,但即使我设法以 10 个为一组,我也会很高兴。

到目前为止,我可以使用它以大约 1000/分钟的速度一次处理一个:

for i in *.json; do mongoimport --writeConcern 0 --db mydb --collection all --quiet --file $i; done

我想我可以使用“jq”来做到这一点,但我不知道如何让 bash 循环一次将 10 个文件传递给 jq。请注意,使用 bash 查找会导致错误,因为文件太多。

使用 jq,您可以使用 --slurp 创建数组,使用 -c 使多行 json 成为单行。但是,我看不出如何将两者组合成一个命令。

如果可能,请帮助解决问题的两个部分。

最佳答案

这是一种方法。为了说明这一点,我使用了 awk,因为它可以小批量读取文件列表,而且它能够执行 jq 和 mongoimport。您可能需要进行一些调整以使整个过程更加健壮、测试错误等等。

思路要么是生成一个可以查看然后执行的脚本,要么就是使用awk的system()命令直接执行命令。首先,让我们生成脚本:

 ls *.json | awk -v group=10 -v tmpfile=json.tmp '
function out() {
print "jq -s . " files " > " tmpfile;
print "mongoimport --writeConcern 0 --db mydb --collection all --quiet --file " tmpfile;
print "rm " tmpfile;
files="";
}
BEGIN {n=1; files="";
print "test -r " tmpfile " && rm " tmpfile;
}
n % group == 0 {
out();
}
{ files = files " \""$0 "\"";
n++;
}
END { if (files) {out();}}
'

一旦您验证了它的有效性,您可以执行生成的脚本,或者将“print ...”行更改为使用“system(....)”

使用jq生成脚本

这里是一个用于生成脚本的仅 jq 方法。由于文件数量很大,下面使用了jq 1.5才引入的特性,所以它的内存占用与上面的awk脚本类似:

def read(n):
# state: [answer, hold]
foreach (inputs, null) as $i
([null, null];
if $i == null then .[0] = .[1]
elif .[1]|length == n then [.[1],[$i]]
else [null, .[1] + [$i]]
end;
.[0] | select(.) );

"test -r json.tmp && rm json.tmp",
(read($group|tonumber)
| map("\"\(.)\"")
| join(" ")
| ("jq -s . \(.) > json.tmp", mongo("json.tmp"), "rm json.tmp") )

调用:

ls *.json | jq -nRr --arg group 10 -f generate.jq

关于json - Bash循环为mongoimport批量合并文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41718679/

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