次の形式の1,200万行を含むCSVファイルがあります。
mcu_i,INIT,200,iFlash, 11593925, 88347,,0x00092684,r,0x4606b570, ok,, 32,single,op-c,0,, 0, 0, 0,
mcu_i,INIT,200,iFlash, 11593931, 88348,,0x00092678,r,0x28003801, ok,, 32,single,op-c,0,, 0, 0, 0,
次のロジックを使用して、6番目の列の値に基づいて行を削除したいと思います。 if (value >= X AND value <= Y ) => 行の削除
gawkを使って解決策を見つけました。
gawk -i inplace -F ',' -v s="$start_marker" -v e="$end_marker" '!($6 <= e && $6 >= s)' myfile.csv
しかし、時間がかかりすぎるので、より良いパフォーマンスを持つ他のソリューションが欲しいです。
ありがとう
ベストアンサー1
長い話を短く
標準出力をgawk
リダイレクト/dev/null
またはパイピングすると、速度がcat
大幅に向上し、実行時間が大幅に短縮されます。
gawk -i inplace [...] myfile.csv >/dev/null
または:
gawk -i inplace [...] myfile.csv | cat
水に飛び込む
@RomeoNinovの場合でも回答元のコマンドよりも実際に速く実行されます。説明したいです。なぜを使用しても高速です-i inplace
。
見たら対話型および非対話型バッファリング部分的にgawk
情報ページ、次の内容が表示されます。
インタラクティブプログラムは平均レベルです。ラインバッファ出力します(つまり、各行を作成します)。非対話型プログラムは、バッファがいっぱいになるまで待ちます。これは複数行の出力にすることができます。
gawk
結果が一部の「in-place」で印刷されても標準出力として印刷されない場合も同様です。
はい
10行のファイルがあります。
$ cat somefile
1
2
3
4
5
6
7
8
9
10
デフォルトでは(ファイルを変更せずにすべての行をそのまま印刷します)、10回のstrace
システムコールが実行されます(ソースファイルの各行に1つずつ)。gawk
write
$ strace -e trace=write -c gawk -i inplace 1 somefile
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00 0.000098 9 10 write
------ ----------- ----------- --------- --------- ----------------
100.00 0.000098 9 10 total
これは対話的に実行され、結果が次のようになるためです。ラインバッファ(gawk
結果が標準出力ではなくファイルに書き込まれても、各行は完了するとすぐに印刷されます。)
stdoutを非対話型にするためにコマンドにリダイレクト/dev/null
(またはパイプで接続)すると、単一のシステム呼び出しのみが呼び出されるように見えます。これは、すべての行をすぐに印刷せず、バッファがいっぱいになった場合にのみ結果をフラッシュするためです。cat
strace
gawk
write
$ strace -e trace=write -c gawk -i inplace 1 somefile > /dev/null
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00 0.000020 20 1 write
------ ----------- ----------- --------- --------- ----------------
100.00 0.000020 20 1 total
もちろん、これは累積的であり、入力ファイルが大きいほど、対話型実行と非対話型実行との差が大きくなります。
一般化する
gawk
対話モードでは、処理が完了すると各行がファイルに書き込まれるため、コマンドは遅くなります。これは、ファイルに何百万回もの書き込みを行うことを意味します。
@RomeoNinovのソリューションは使用しないため、元のコマンドよりも高速ですが、出力を一時ファイルにリダイレクトするため、inplace
非対話型モードで実行され、バッファフラッシュを最適化し、ファイルgawk
操作の書き込み操作を少なくします。
しかし、質問に提供されたコマンドは引き続き使用できますが、stdoutを/dev/null
(とにかく空にするため)リダイレクトまたはパイプするとcat
すぐに実行されます。
gawk
次のように使用する場合のセキュリティリスクinplace
私は自分の仕事でうまくいくと予測不可能な結果をもたらす可能性があるという@RomeoNinovのコメントに全く同意しませんが、@OlivierDulacのコメント-i inplace
これは、一般的な使用がセキュリティの脆弱性と見なされる理由を説明する便利な答えを提供します。この問題を解決する方法安全な方法で実行してください。