我确信有人有以下需求,有什么快速方法可以按行拆分大型 .gz 文件?底层文本文件有 1.2 亿行。我没有足够的磁盘空间来一次压缩整个文件,所以我想知道是否有人知道可以将文件(.gz 或内部 .txt)拆分为 3x 40mn 行文件的 bash/perl 脚本或工具。即调用它:
bash splitter.sh hugefile.txt.gz 4000000 1
would get lines 1 to 40 mn
bash splitter.sh hugefile.txt.gz 4000000 2
would get lines 40mn to 80 mn
bash splitter.sh hugefile.txt.gz 4000000 3
would get lines 80mn to 120 mn
也许是执行一系列这样的操作来解决,或者 gunzip -c 是否需要足够的空间来解压整个文件(即原始问题): gunzip -c hugefile.txt.gz | head 4000000
注意:我无法获取额外的磁盘。
谢谢!
答案1
如何最好地做到这一点取决于你想要什么:
- 您想提取大文件中的某个部分吗?
- 或者您想一次性创建所有部分?
如果你想要文件的单个部分,你的想法gunzip
是head
正确的。你可以使用:
gunzip -c hugefile.txt.gz | head -n 4000000
这将在标准输出上输出前 4000000 行 - 您可能需要附加另一个管道来实际对数据执行某些操作。
head
要获取其他部分,可以使用和的组合tail
,例如:
gunzip -c hugefile.txt.gz | head -n 8000000 |tail -n 4000000
获取第二个块。
也许可以采取一系列措施来解决,或者 gunzip -c 是否需要足够的空间来解压整个文件
不,它gunzip -c
不需要任何磁盘空间 - 它在内存中完成所有操作,然后将其输出到标准输出。
如果你想创造一次性完成所有部件,使用单个命令创建它们更有效率,因为这样输入文件只会被读取一次。一个好的解决方案是使用split
;有关详细信息,请参阅 jim mcnamara 的回答。
答案2
要拆分的管道使用 gunzip -c 或 zcat 打开文件
gunzip -c bigfile.gz | split -l 400000
向拆分命令添加输出规范。
答案3
当您在(不可倒带的)流上工作时,您将需要使用 tail 的 '+N' 形式来获取从第 N 行开始的行。
zcat hugefile.txt.gz | head -n 40000000
zcat hugefile.txt.gz | tail -n +40000001 | head -n 40000000
zcat hugefile.txt.gz | tail -n +80000001 | head -n 40000000
答案4
直接将.gz文件拆分为.gz文件:
zcat bigfile.gz | split -l 400000 --filter='gzip > $FILE.gz'
我认为这就是 OP 想要的,因为他没有太多空间。