在进行内联压缩时,将大的压缩日志文件拆分为压缩的X行块

时间:2010-08-18 12:11:50

标签: bash shell

我的情况如下:一个大的(10GB)压缩文件,包含一些文件(~60),总无压缩大小为150GB。

我希望能够将大的压缩日志文件分割成具有一定数量行的部分(即:100万)。

想要使用拆分,因为它涉及完全解压缩原始文件,而且我没有那么多可用的磁盘空间。

到目前为止我所做的是:

#!/bin/bash
SAVED_IFS=$IFS
IFS=$(echo -en "\n\b")
for file in `ls  *.rar` 
do
    echo Reading file: $file
    touch $file.chunk.uncompressed
    COUNTER=0
    CHUNK_COUNTER=$((10#000))
    unrar p $file while read line; 
    do
        echo "$line" >> $file.chunk.uncompressed
        let COUNTER+=1
        if [ $COUNTER -eq 1000000 ]; then
            CHUNK_COUNTER=`printf "%03d" $CHUNK_COUNTER;`
            echo Enough lines \($COUNTER\) to create a compressed chunk \($file.chunk.compressed.$CHUNK_COUNTER.bz2\)
            pbzip2 -9 -c $file.chunk.uncompressed > $file.chunk.compressed.$CHUNK_COUNTER.bz2
            #  10# is to force bash to count in base 10, so that 008+ are valid
            let CHUNK_COUNTER=$((10#$CHUNK_COUNTER+1))          
            let COUNTER=0
        fi  
    done
    #TODO need to compress lines in the last chunk too
done
IFS=$SAVED_IFS

我不喜欢它,是因为我受到写入速度的限制,然后读取未压缩的块(~15MB / s)。 直接从压缩文件中读取未压缩的stram的速度约为80MB / s。

如何直接写入压缩文件,我是如何调整此脚本直接流式传输每个块的有限行数?

2 个答案:

答案 0 :(得分:2)

您可以将输出传输到循环,在该循环中使用head来剪切文件。

$ unrar p $file | ( while :; do i=$[$i+1]; head -n 10000 | gzip > split.$i.gz; done )

你唯一需要解决的问题是如何终止循环,因为这将继续生成空文件。 这是留给读者的练习。

压缩空文件会给出一些输出(对于gz,它是26个字节)所以你可以测试一下:

$ unrar p $file |
       ( while :; do
           i=$[$i+1];
           head -n 10000 | gzip > split.$i.gz;
           if [ `stat -c %s split.$i.gz` -lt 30 ]; then rm split.$i.gz; break; fi;
       done )

答案 1 :(得分:-1)

如果您不介意将文件包装在tar文件中,那么可以使用tar为您分割和压缩文件。

您可以使用tar -M --tape-length 1024创建1兆字节的文件。请注意,每100兆字节的tar后,会要求您在再次开始写入文件之前按Enter键。因此,您必须使用自己的脚本包装它并在执行此操作之前移动生成的文件。