【发布时间】:2019-09-06 19:40:36
【问题描述】:
要求:我有一个 .gz 格式的 Json 文件。因此,压缩后的大小约为 500 MB。当我提取它时,json 文件几乎变成了大约 10 GB。提取的 JSON 文件逐行包含单个 JSON 对象。我想要的是使用任何 bash 脚本或 python 程序基于字段ps 对文件进行排序。
由于文件太大,不建议将其加载到内存中。因此,我使用 gzcat 和 cat bash 命令流式传输 JSON 数据,然后将它们通过管道传输到 jq 以进行排序。但要么系统在此过程中没有响应,要么我在 output.json 中得到空文件
>cat sth2.json | parallel --pipe --group --block 1000M --recend '\n}\n' "jq -s -c 'sort_by(.ps) | .[]'" > "output.json"
>gzcat sth2.json.gz | parallel --pipe --group --block 1000M --recend '\n}\n' "jq -s -c 'sort_by(.ps) | .[]'" > "output.json"
硬件: 16GB 内存, 酷睿 i5 处理器
示例 JSON 数据:-
{
"ps":"abc"
....
}
{
"ps":"def"
......
}
{
"ps":"abc"
....
}
预期输出:
{
"ps":"abc"
....
}
{
"ps":"abc"
....
}
{
"ps":"def"
....
}
我不明白我做错了什么。谁能建议如何对如此巨大的 JSON 文件进行排序? 我关注的链接: https://github.com/joelpurra/jq-hopkok/tree/master/src/parallelism
另外,没有 Hadoop 的情况下,我可以通过任何 Map reduce 来做些什么吗?
方法 1:将数据流式传输到本地 Sqlite DB。
import sqlite3
import fileinput
PATH=".../sqlite-snapshot-201904101324/testDB.db"
insert_query="INSERT INTO feeds (data) VALUES (?)"
def db_connect(db_path=PATH):
con = sqlite3.connect(db_path)
return con
con = db_connect() # connect to the database
cur = con.cursor() # instantiate a cursor obj
record_count = 0
for line in fileinput.input():
cur.execute(insert_query,(line,))
命令行:
>gzcat sth.json.gz | python insert.py
【问题讨论】:
-
那么如何对 JSON 文件进行排序呢?有没有可用的实用程序或其他任何东西?
-
是的,没错,我测试了大约 20 行,我可以看到它们。
-
如果可以,例如使用排序键为行添加前缀,以便它们可以作为文本而不是 JSON 进行排序,然后 GNU 排序可以轻松地对 10GB 以上的文件进行排序,而无需将它们加载到内存中。
-
我将“单个 JSON 对象逐行”解释为 JSONL
-
@Tomalak 在上面的评论中您提到使用 python 将 .gz 文件内容流式传输到 sqlite。您能否提供更多详细信息如何做到这一点
标签: python json bash sorting jq