数行で文字列を置き換える必要がある25GBのテキストファイルがあります。 sed
はうまく使用できますが、実行に非常に長い時間がかかります。
sed -i 's|old text|new text|g' gigantic_file.sql
これを行うためのより速い方法はありますか?
あなたが試すことができます:
sed -i '/old text/ s//new text/g' gigantic_file.sql
これから ref :
速度の最適化:実行速度を上げる必要がある場合(入力ファイルが大きいか、プロセッサやハードディスクが遅いため)、 "s /.../。 ../ "命令。
以下は、10Gファイルの比較です。前:
$ time sed -i 's/original/ketan/g' wiki10gb
real 5m14.823s
user 1m42.732s
sys 1m51.123s
後:
$ time sed -i '/ketan/ s//original/g' wiki10gb
real 4m33.141s
user 1m20.940s
sys 1m44.451s
短い答えは「いいえ」です。この種の操作の制限要因はディスクIOです。 25GBのディスクをこれ以上速くストリーミングする方法はありません。インプレース編集を行わず、sed
の結果を別のドライブに書き込んだ場合(使用可能なドライブがある場合)、マイナーな改善が見られることがあります。別のユーザーに書き込みを行うと、結果として競合がわずかに少なくなります。
あなたmight各行に正規表現エンジンを使用しないことで少しスピードアップできる-たとえば、Perlを使用する(sed
でこれを実行できると確信していますが、構文はわかりません)-これは10,000行目から始まります。
Perl -pe '$. > 10_000 && s/old_text/new_text/g'
そして、RE(メタ文字)になんらかの複雑さが存在する場合、それらを最小限に抑えるとわずかに正規表現エンジンの効率が向上します。
新しいテキストと古いテキストが同じ長さの場合、ファイル全体をコピーする代わりに、ファイルをシークして変更されたバイトのみを書き込むことができます。そうしないと、移動する大量のデータに閉じ込められます。
注:これはトリッキーであり、カスタムコードの記述が含まれます。
CまたはC++で作業している場合はfseekのマニュアルページを参照してください。または、シークおよび書き込みシステムコールに使用する言語ラッパーを参照してください。
コマンドラインのみを使用するように主張し、テキストのバイトオフセットを取得できる場合は、慎重に記述された "dd"コマンドを使用して、置換テキストを適切な場所に書き込むことができます。