gz形式の40GBファイルがあります。cksum
このファイルの圧縮されていない形式のレコード数を見つけたいと思います。私の方法の1つは次のとおりです。
- 解凍されたファイルの使用
gunzip
- ファイルを解凍するには、
wc
次のコマンドを使用します。cksum
- ファイル圧縮を再利用してください
gzip
。
この方法の問題は、ファイルの抽出と圧縮に時間がかかることです。約30~40分ほどかかる場合があります。別のアプローチは、zcat
レコード数を数えることです。cksum
zcat <file name> | wc -l
zcat <file name> | cksum
この方法は時間がかかりませんが、zcat
同じファイルに対して2回使用されます。もっと良い方法がありますか?たぶん、レコード数の合計を見つけるためにコマンドが使用されますかcksum
?
答え1
moreutils
Debian(および他の場所)のパッケージには、共通ユーティリティの小さな宝物倉庫が含まれています。
その一つはですpee(1)
。tee(1)
これは、出力を(複数の)ファイルに書き込むのではなく、(複数の)コマンドにパイプするのと似ています。使い方はとてもシンプルで直感的です。
$ zcat foo.gz | pee md5sum wc
0a22adb99b92b4c5ad6beba9694238a3 -
403 2372 27766
答え2
tee
バッシュが使えますプロセスの交換これ:
$ zcat foo.gz | tee >(md5sum >&2) | wc
6f869e2acc27a0330b10d9ffa6655e7b -
36568 45710 2743552
ファイルの圧縮を一度解凍し、解凍したデータをtee
入力ファイルとしてファイルに渡し、ファイルmd5sum
に出力を標準エラーとして印刷するように指示し(キャプチャされていない| wc
)、出力も渡しますwc
。
答え3
ディスク容量は問題にならないようです。最も簡単な方法は、一時ファイルにファイルを解凍し、そのファイルに対して2つのコマンドを実行することです。完了したら、一時ファイルを削除します。
gunzip -c file.gz >tmpname
wc -l tmpname
cksum tmpname
rm tmpname
必要に応じてgunzip -c
またはに置き換えることができますgzip -d -c
。zcat
答え4
使用する場合zsh
:
{zcat file.gz} > >(wc -l) > >(cksum)
stdoutは2回リダイレクトされるため、zshはそれを内部ingプロセスのパイプに置き換えてtee
出力をwc -l
andに送信しますcksum
。
wc
とは同時にcksum
実行され、どちらが最初に結果を出力するかは定義されていません。