2009-05-09 4 views
1

私は本当に大きなログファイル(9GB - 私はそれを修正する必要があることを知っています)を私の箱に持っています。私はチャンクに分割して、バックアップのためにAmazon S3にアップロードする必要があります。 S3の最大ファイルサイズは5GBです。だから、私はこれをいくつかの塊に分割し、それぞれをアップロードしたいと思います。UNIXのオフセット値を持つログファイルを分割するにはどうすればよいですか?

ここではキャッチですが、私は自分のサーバーに無料で5GBしか持っていないので、単純なUNIXの分割はできません。ここで私は何をしたいです:

  1. ログファイルの最初の4ギガバイトを取得し、別々のファイルに吐き出す(セグメント1、それを呼び出す)
  2. S3にアップロードSEGMENT1。
  3. rm segment1は空きスペースを確保します。
  4. ログファイルから中央の4GBを取得し、s3にアップロードします。以前と同様にクリーンアップ
  5. 残りの1GBを取得してS3にアップロードします。

オフセットで分割する適切なunixコマンドが見つかりません。スプリットは物事を同じチャンクで行い、csplitは必要なものを持っていないようです。どんな勧告?

答えて

3

1つ(畳み込み)のソリューションは、最初に圧縮することです。テキストログファイルは、9Gから5Gのかなり下に簡単に移動し、元のファイルを削除して9Gの空き容量を確保します。

次に、圧縮ファイルをsplitで直接パイプして、ディスク領域を使い切らないようにします。結局、圧縮ファイルとアップロード用の3つのファイルが完成します。

アップロードしてから削除し、元のログを解凍します。

=====

より良い解決策は、単に個々の部品(たとえば300万)行をカウントし、抽出するためにawkスクリプトを使用して送信することです:で、その後

awk '1,1000000 {print}' biglogfile > bit1 
# send and delete bit1 

awk '1000001,2000000 {print}' biglogfile > bit2 
# send and delete bit2 

awk '2000001,3000000 {print}' biglogfile > bit3 
# send and delete bit3 

をもう一方の端、あなたはどちらかのプロセスbit1個別bit3経由することができ、またはそれらを再結合:

mv bit1 whole 
cat bit2 >>whole ; rm bit2 
cat bit3 >>whole ; rm bit3 

そして、もちろん、この分割はのいずれかで行うことができますUNIXの標準テキスト処理ツール:perlpythonawkhead/tailのコンボです。それはあなたが快適であるかどうかによって異なります。

+0

なぜ私はファイルを圧縮するとは思わなかったのですか?それは622Mに下がり、アップロードするのに十分小さかった。 – Ish

+0

それは良い解決策です、Ish。私はちょうど最初の文の後に私の罠を閉めることができたように見える:-) – paxdiablo

2

まず、gzip -9ログファイル。何か非常に

#!/bin/env sh 

chunk_size = 2048 * 1048576; #gigs in megabytes 
input_file = shift;  

len = `stat '%s' $input_file` 
chunks = $(($len/$chunk_size + 1)) 

for i in {0...$chunks} 
do 
    dd if=$input_file skip=$i of=$input_file.part count=1 bs=$chunk_size 
    scp $input_file.part servername:path/$input_file.part.$i 
done 

私はちょうど私の頭の上からこれをでploppedので、それをそのまま動作するかどうかは知らないが、:

その後、ddは、使用する小さなシェルスクリプトを書きますこれに似たものが必要です。

+0

ありがとう私はddコマンドthats有用について知らなかった。 – Ish

2

ddを使用できます。ブロックごとにbs(メモリバッファサイズ)、skip(スキップするバッファ数)、count(コピーするバッファ数)を指定する必要があります。

# For the first 4Gig 
dd if=myfile.log bs=10M skip=0 count=400 of=part1.logbit 
<upload part1.logbit and remove it> 
# For the second 4Gig 
dd if=myfile.log bs=10M skip=400 count=400 of=part2.logbit 
... 

また、あなたは転送しようとしているデータを圧縮するの恩恵を受ける可能性があります:

dd if=myfile.log bs=10M skip=800 count=400 | gzip -c > part3.logbit.gz 

よりフレンドリーな方法があるかもしれませんので、あなたはどうしたら、10Megのバッファサイズを使用して

ddにはいくつかの欠点があります。小さなバッファサイズを使用すると、はるかにゆっくりと実行されます。しかし、bsの倍数だけファイル内をスキップ/シークすることができます。だから、素数オフセットからデータを読み始めたいのであれば、あなたは本当のフィドルです。とにかく私は逃げる。

+0

行または区切り文字をスキップできますか? –

0

Coreutils splitは、最後のセクションを除いて、等しいサイズの出力セクションを作成します。

split --bytes=4GM bigfile chunks 
+0

彼は、彼の質問では、自分のサーバー上のディスクスペースが限られているため、スプリットを実行できないと言っていました。 –

関連する問題