当前位置: 首页 > 面试题库 >

使用bash或python排序巨大的JSON文件

闽哲
2023-03-14
问题内容

要求 :我有一个.gz格式的Json文件。因此,压缩后的大小约为500 MB。当我提取它时,json文件几乎变成了大约10
GB。提取的JSON文件逐行包含单个JSON对象。我想要的是ps使用任何bash脚本或python程序基于字段对文件进行排序。

由于文件太大,因此不建议将其加载到内存中。因此,我使用了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 RAM,核心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

问题答案:

这是基于其中一项评论中的建议的解决方案:

如果您可以在行前面加上sort键,以便可以将它们作为文本而不是JSON进行排序,那么GNU
sort可以轻松地对10GB以上的文件进行排序,而无需将其加载到内存中。–那个人

您可以使用jq沿着以下行执行此操作:

jq -cr '"\(.ps)\t\(.)"'

这将产生带有制表符分隔值的行,如下所示:

abc {"ps":"abc","x":0}
abc {"ps":"abc","x":1}

使用-c选项可确保将每一对(即排序键和对象)写入一行。

现在,您可以轻松地对行进行排序,例如使用sort;然后使用例如cut剥离.ps字段。

最后,如果您确实希望格式化输出,则可以再次使用jq(例如jq .),这是因为jq默认情况下是面向流的。

警告

以上假设.ps值不带制表符。如果不是这种情况,则可以使用其他字段分隔符,也可以:

jq -cr '([.ps] | @tsv) + "\t" + tostring'


 类似资料:
  • 问题内容: 我有相对较小的对象的巨大(〜7GB)json数组。 有没有一种相对简单的方法可以过滤这些对象而无需将整个文件加载到内存中? --stream 选项看起来合适,但我不知道如何将[path,value]的流折叠到原始对象。 问题答案: jq 1.5具有流解析器。jq FAQ提供了一个示例,该示例如何将JSON对象的顶级数组转换为其元素流: 这可能足以满足您的目的,但是值得注意的是setpa

  • 问题内容: 我正在处理一个很大的文本文件(755Mb)。我需要对行进行排序(大约1890000),然后将它们写回到另一个文件中。 问题是我无法将行存储在内存中的集合中,因为我收到了Java堆空间异常(即使我最大程度地扩展了它)。(已经尝试过!) 我不能用excel打开它并使用排序功能,因为文件太大并且无法完全加载。 我考虑过使用数据库..但是我认为编写所有行然后使用SELECT查询就执行时间而言太

  • 问题内容: 我目前正在尝试从Python 2.7中的.csv文件中读取数据,该文件最多包含100万行和200列(文件范围从100mb到1.6gb)。对于少于300,000行的文件,我可以(非常缓慢地)执行此操作,但是一旦超过该行,就会出现内存错误。我的代码如下所示: 在getstuff函数中使用else子句的原因是,所有符合条件的元素都将一起列在csv文件中,因此,经过它们以节省时间时,我离开了循

  • 问题内容: 我一直试图在bash中的制表符分隔文件的每一列中获取唯一值。因此,我使用了以下命令。 它工作正常,我可以在列中获取唯一值,其计数如下 我要执行的操作不是按列值名称(在此示例中为OS名称)进行排序,而是要按计数对它们进行排序,并可能以这种输出格式将计数放在第二列中。因此它必须看起来像: 我该怎么做呢? 问题答案: 采用: 所述排序以相反的顺序,使用第一字段为数值。在简单地反转列的顺序。您

  • 问题内容: 我正在尝试使用gson库(http://code.google.com/p/google-解析一些巨大的JSON文件(例如http://eu.battle.net/auction- data/258993a3c6b974ef3e6f22ea6f822720/auctions.json )JAVA中的gson / )。 我想知道解析这种大文件(约80k行)的最佳方法是什么,以及您是否知道