2010-08-18 75 views
1

我的情況如下:一個大的(10GB)壓縮文件,其中包含一些文件(〜60),總未壓縮大小爲150GB。將大型壓縮日誌文件拆分爲X行的壓縮塊,同時進行內聯壓縮

我希望能夠將大型壓縮日誌文件分割成部分,其中包含一定數量的行(即: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。

如何使這個腳本能夠直接在每個塊中直接寫入有限數量的行,同時直接寫入壓縮文件?

+1

'IFS = $'\ n \ b''(你真的想),'CHUNK_COUNTER = $((10#000))'與* CHUNK_COUNTER = 0相同(只是使用中間變量而不是在輸出和遞增時來回轉換) – 2010-08-18 15:11:54

+2

'用於* .rar'中的文件 - 不需要'ls'。 – 2010-08-18 15:14:51

回答

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) 
+0

不得不爲FreeBSD適應它,但是它隨後成爲了一種魅力。所以感謝和+1 – CodeReaper 2012-12-14 11:43:43

-1

如果您不介意將文件包裝在tar文件中,那麼您可以使用tar爲您分割和壓縮文件。

您可以使用tar -M --tape-length 1024創建1兆字節的文件。請注意,在每100兆字節的tar之後,它會要求您在輸入文件之前再次按下輸入。所以你必須用自己的腳本來包裝它,然後才能移動生成的文件。

+0

Waht我不喜歡這個,它強制它是互動的。 – elhoim 2010-08-18 12:42:05