在Linux中,如何将输入流压缩为多个输出文件?

时间:2014-05-16 16:56:24

标签: linux split compression bigdata

我知道怎么做:

commandGeneratingLotsOfSTDOUT | bzip2 -z -c > compressed.bz2

我也知道如何做到这一点:

commandGeneratingLotsOfSTDOUT | split -l 1000000

但我不知道该怎么做:

commandGeneratingLotsOfSTDOUT | split -l 1000000 -compressCommand "bzip2 -z -c"

如果上面的内容尚未100%清除,我正在运行一个生成TB或两个输出的命令。我希望将输出拆分为N行(本例中为100万行)的块,并将每个块压缩为bzip2并存储在文件中。

现在我做的是:

commandGeneratingLotsOfSTDOUT | split -l 1000000
foreach fileGenerated { bzip2 -z thatFile }

这为每个文件添加了额外的写入磁盘并从磁盘读取(并再次写入磁盘,尽管已压缩)!由于文件都大于RAM,因此转换为实际磁盘使用情况。

2 个答案:

答案 0 :(得分:5)

怎么样:

cmdWithLotsOfSTDOUT | split -l 1000000 --filter 'bzip2 > "$FILE.bz2"'

一个例子:

$ ls
afile

$ cat afile
one
two
three
four
five
six
seven
eight
nine
ten

$ cat afile | split -l 2 --filter='bzip2 > "$FILE.bz2"'

$ ls
afile  xaa.bz2  xab.bz2  xac.bz2  xad.bz2  xae.bz2

$ bzip2 -dc xac.bz2
five
six

$

答案 1 :(得分:0)

我将回答这个问题,但希望我不必将其标记为正确答案。

GNU coreutils是开源的。这里有一个回购,例如:https://github.com/goj/coreutils。它包含split命令的源代码split.c:https://github.com/goj/coreutils/blob/rm-d/src/split.c。可以将其修改为:

  1. 添加将分割块通过其传输的程序作为输入参数的功能
  2. 将分段传递给程序应该写入的文件。
  3. 这不是最理想的,因为必须精通C和GNU编程实践等。我有技术诀窍这样做,但除非我知道补丁会被接受,否则我会犹豫不决回到主线。可能需要与#gnu中的优秀人员协调。

    另一种方法是编写自己的splitCompress程序/脚本。我实际上是这样做的,在Perl中,它的性能比问题中提出的方法低大约10倍。可能有一些方法可以优化Perl以传输大量数据。我在这里放了一份Perl程序:http://faemalia.com/Technology/splitCompress.pl.html。通过一些调整,这个程序可以成为一个伟大的正确答案的基础。

    编辑:我只是查看了日志,实际上是Perl" splitCompress.pl"程序的速度与问题中概述的方法大致相同。它的性能不会低10倍。