きっと誰かが以下のようなニーズを抱えていると思いますが、巨大な .gz ファイルを行ごとに分割する簡単な方法は何でしょうか? 基になるテキスト ファイルには 1 億 2000 万行あります。ファイル全体を一度に gunzip するのに十分なディスク領域がないので、ファイル (.gz または内部の .txt) を 3 つの 4000 万行のファイルに分割できる 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
2番目のブロックを取得します。
これらを連続して実行するのが解決策でしょうか、それともgunzip -cではファイル全体を解凍するのに十分なスペースが必要でしょうか
いいえ、gunzip -c
ディスク スペースは必要ありません。すべてをメモリ内で実行し、それを stdout にストリーム出力します。
作成したい場合はすべての部品を一度に、入力ファイルが一度だけ読み込まれるため、すべてを 1 つのコマンドで作成した方が効率的です。 1 つの良い解決策は を使用することですsplit
。詳細については、jim mcnamara の回答を参照してください。
答え2
パイプを分割するには、gunzip -c または zcat を使用してファイルを開きます。
gunzip -c bigfile.gz | split -l 400000
分割コマンドに出力仕様を追加します。
答え3
(巻き戻し不可能な) ストリームで作業している場合は、行 N 以降から始まる行を取得するために、tail の '+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 が望んでいたのはこれだと思います。スペースがあまりないからです。