
私は7.6GBのgzipファイルのレコードをカウントしようとしています。zcat
このコマンドの使用方法はほとんどありません。
$ zcat T.csv.gz | wc -l
423668947
この方法は機能しますが、時間がかかりすぎます(計算に10分以上)。私は次のようなより多くの方法を試しました。
$ sed -n '$=' T.csv.gz
28173811
$ perl -lne 'END { print $. }' < T.csv.gz
28173811
$ awk 'END {print NR}' T.csv.gz
28173811
3つのコマンドはすべて非常に高速に実行されますが、誤った数の28173811が表示されます。
最小時間でレコード計算を実行するには?
答え1
言及したsed
、perl
とコマンドはawk
正確かもしれませんが、すべて読んでください。圧縮データを入力し、その中に改行文字を数えます。これらの改行は、圧縮されていないデータの改行とは無関係です。
圧縮されていないデータの行数を計算するには、解凍できません。あなたのアプローチがzcat
正しいアプローチであり、データが大きすぎるため〜する開梱には時間がかかります。
圧縮と解凍を処理するほとんどのユーティリティは、gzip
これを行うために同じ共有ライブラリルーチンを使用する可能性が高いです。作業を高速化する唯一の方法は、zlib
基本ルーチンよりも高速なルーチン実装を見つけて、zcat
それを使用するために再構築することです。
答え2
unpigzを使用してください。
Kosalonandaの答えは正しいです。〜するコンテンツをスキャンする前に、ファイル全体を解凍する必要があります。/bin/gunzip
単一コアでできるだけ早くこれを行います。豚豚gzip
複数のコアを使用できる並列実装です。
pigz
残念ながら、通常のgzipファイル自体の解凍は並列化できませんが、読み取り、書き込み、チェックサムなどの関連タスクを別のスレッドで実行する改善されたバージョンのgzipを提供します。一部の高速ベンチマークでは、コアi5システムよりもほぼ倍速です。gunzip
unpigz
unpigz
gunzip
pigz
お気に入りのパッケージマネージャを使用してインストールし、代わりにunpigz
使用してくださいgunzip
。したがって、あなたのコマンドは次のようになります。unpigz -c
zcat
$ unpigz -c T.csv.gz | wc -l
もちろん、これらすべては、ボトルネックがディスクではなくCPUであると想定しています。
答え3
すべての配管の問題は、基本的に作業量が2倍になるということです。解凍速度に関係なく、データはまだ別のプロセスに移動する必要があります。
PerlはPerlIO::gzipgzipで圧縮されたストリームを直接読み取ることができます。したがって、減圧速度が一致しない場合でも、次の利点がありますunpigz
。
#!/usr/bin/env perl
use strict;
use warnings;
use autouse Carp => 'croak';
use PerlIO::gzip;
@ARGV or croak "Need filename\n";
open my $in, '<:gzip', $ARGV[0]
or croak "Failed to open '$ARGV[0]': $!";
1 while <$in>;
print "$.\n";
close $in or croak "Failed to close '$ARGV[0]': $!";
13MB gzip圧縮ファイル(1.4GBに解凍)を持つ古いコンピュータで試しました。16GB RAMを搭載した2010年のMacBook Proそして古いものThinkPad T400には8GBのRAMが搭載されています。ファイルはすでにキャッシュにあります。 Macでは、Perlスクリプトはパイプを使用するよりはるかに高速ですが(5秒対22秒)、ArchLinuxではunpigzに敗北します。
$時間-p ./gzlc.pl spy.gz 1154737 実際の4.49 ユーザー 4.47 システム0.01
比較的
$時間-p unpigz -c spy.gzトイレ-l | 1154737 実際の3.68 ユーザー 4.10 システム 1.46
そして
$時間-p zcat spy.gzトイレ-l | 1154737 レアル6.41 ユーザー 6.08 システム0.86
明らかに、unpigz -c file.gz | wc -l
スピードの面では使用量が勝者です。そしてどんなに短くても、単純なコマンドラインは確かにプログラム作成よりも優れています。
答え4
これは zgrep
フラグ-c
と$
パラメータを使用して行うことができます。
この場合、-c はコマンド出力に行数を一致させるように指示し、正規表現 $ は行末と一致するため、すべての行またはファイルと一致します。
zgrep -c $ T.csv.gz
@StéphaneChazelasが述べたように - 元の提案と同様のパフォーマンスを提供する必要があるスクリプトzgrep
だけです。zcat
grep
zcat | wc -l