多核gzip解压缩,将输出文件(csv)拆分为1Gb/file的部分

多核gzip解压缩,将输出文件(csv)拆分为1Gb/file的部分,csv,gzip,bigdata,Csv,Gzip,Bigdata,我有10Gb gzip存档(未压缩约60Gb) 有没有一种方法可以通过多线程+动态拆分将输出按1Gb/part(n行/part,)拆分为多个部分来解压缩此文件 如果我这样做: pigz -dc 60GB.csv.gz | dd bs=8M skip=0 count=512 of=4G-part-1.csv 我可以得到一个4Gb的文件,但它并不关心总是从下一行开始,所以我的文件中的行不会正确结束 另外,正如我所指出的,我的GCE实例与持久磁盘的最大块大小为33kb,因此我实际上无法使用上述命令,

我有10Gb gzip存档(未压缩约60Gb)

有没有一种方法可以通过多线程+动态拆分将输出按1Gb/part(n行/part,)拆分为多个部分来解压缩此文件

如果我这样做:

pigz -dc 60GB.csv.gz | dd bs=8M skip=0 count=512 of=4G-part-1.csv
我可以得到一个4Gb的文件,但它并不关心总是从下一行开始,所以我的文件中的行不会正确结束

另外,正如我所指出的,我的GCE实例与持久磁盘的最大块大小为33kb,因此我实际上无法使用上述命令,但必须打印如下内容:

pigz -dc 60GB.csv.gz | dd bs=1024 skip=0 count=4194304 of=4G-part-1.csv

pigz -dc 60GB.csv.gz | dd bs=1024 skip=4194304 count=4194304 of=4G-part-2.csv

pigz -dc 60GB.csv.gz | dd bs=1024 skip=$((4194304*2)) count=4194304 of=4G-part-3.csv
所以,我必须做一些技巧,总是从新行开始文件

更新:

zcat 60GB.csv.gz |awk 'NR%43000000==1{x="part-"++i".csv";}{print > x}'

成功了

除非它是专门为这样的操作准备的,或者除非为此目的建立了索引,否则不会。gzip格式本质上要求在流中的任何点之前解压缩数据,以便在流中的该点之后解压缩数据。所以它不能并行化

解决方法是a)使用同步点重新压缩gzip文件并保存这些位置,或者b)遍历整个gzip文件一次,然后在这些点上创建另一个具有上一个上下文的入口点文件

对于a),提供了
Z_FULL_FLUSH
操作,在流中插入同步点,您可以从中开始解压缩,而无需以前的历史记录。您可能希望节省地创建这样的点,因为它们会降低压缩


对于b),提供了一个如何在gzip文件中构建索引的示例。为了构建索引,您需要按顺序遍历流一次,但这样做之后,您就可以在保存的位置开始解压缩。

根据您在问题中提到的大小,似乎可以得到6:1的压缩。这对文本来说似乎不太好,但无论如何

正如马克所说的,你不能只在gz文件中插入中间流,然后期望在一条新的线路上着陆。您的
dd
选项将不起作用,因为dd只复制字节,它不会检测压缩的换行符。如果索引不在此范围内,以下命令行解决方案可能会有所帮助:

$ gzcat 60GB.csv.gz | awk -v n=1 '!NR%20000000{n++} {print|("gzip>part-"n".gz")}'
这将解压缩您的文件,以便我们可以计算行数,然后处理流,每20000000行更改一次输出文件名。您可以在上面代码中看到“gzip”的地方调整重新压缩选项

如果不希望压缩输出,可以简化行的最后一部分:

$ gzcat 60GB.csv.gz | awk -v n=1 '!NR%3500000{n++} {print>("part-"n".csv")}'
您可能需要调整行数,以获得接近目标文件大小的内容

请注意,如果shell是csh/tcsh,则可能必须在awk脚本中转义感叹号,以避免将其解释为历史引用

更新

如果您想获取脚本正在执行的操作的状态,awk可以这样做。类似这样的事情可能很有趣:

$ gzcat 60GB.csv.gz | awk -v n=1 '!NR%3500000{n++} !NR%1000{printf("part=%d / line=%d\r",n,NR)} {print>("part-"n".csv")}'

这应该每千行向您显示当前的零件和行号。

您是否有足够的内存(即~10GB)来保存此文件?如果我能找到一种工作方法,我会找一些。我建议您先获取内存,然后看看性能如何。当您给应用程序足够的内存时,这个问题可能会随着您获得的性能而变得无效。特别是对于“BigData”,当内存不足时,整个系统就会瘫痪。我pigz可以提供类似多线程的方式来解压gz,因为它使用一个线程进行解压,它会启动3个额外的线程进行读、写和校验计算。哦,对不起,我似乎不明白你的意思(我的英语不够好)由于gzip流的串行特性,pigz在使用多个处理器解压时只提供了很小的加速。但是,在n个处理器上压缩时,pigz提供了n个加速因子。tnx,m8,这是一个很好的加速因子。。但你能再帮我一次吗,我对awk不是很熟悉,只是无法获得命令来创建几个200万行的文件:它只创建一个大文件part 1.csv,并将所有内容打印到它。Hrm。真奇怪。文件中有多少行?(
gzcat file.gz | wc-l
将告诉您。)条件
!NR%20000000
确实应该每两千万行评估一次为真。你能不能试着把这个数字减少到一些容易看到的数字,比如几千个,然后看看你是否有很多文件?我已经用awk命令的一个变体更新了答案,它应该会给你关于跑步进度的反馈。