0

私は、mysqldump の出力を生成時に変更するプログラムに取り組んでいます。現在、mysqldump の出力を固定バイト数のチャンクで読み取るコードがあります。正規表現の一致と、このテキストを読み取ったときに正規表現の置換の両方を実行できる必要があります (最終的なファイル サイズが数ギガバイトであるため、最終的なテキスト出力で正規表現を実行することはできません)。私は PHP でコードを書いていますが、問題 (およびその解決策) は言語に依存しないはずだと思います。

現在、私が持っているものの疑似コードは次のようになります。

$previous_chunk = "";
while (!end_of_file($reader)) {
    $chunk = $reader.read() //read in a few thousand characters from the file
    $double_chunk = $previous_chunk + $chunk;
    // do regular expressions on the double chunk (to catch matches that span the chunk boundary)
    $output_file.write($chunk);
    $previous_chunk = $chunk;
}

これは 2 つの問題で座礁します。1 つ目は、各チャンクが正規表現によって 2 回評価されるため、チャンク内で一致が発生した場合 (チャンクの境界にまたがっていない場合)、一致するテキストが 1 回しか発生しない場合でも、その一致が 2 回トリガーされます。2 つ目の問題は、これでもまだマッチの置換を行うことができないことです。正規表現はテキストを置き換えますが、出力ファイルに$double_chunk書き込むだけ$chunkで、置換の影響を受けません。

私が考えていたことの 1 つは、正規表現が複数の行 (文字で区切られて\nいる) にまたがる必要があるとは思わないので、プログラムで 2 番目のバッファーを作成し、完了した行でのみ正規表現を実行し、次に書き込むことができるということでした。チャンクごとではなく、行ごとにターゲット ファイルに出力します。残念ながら、mysqldump からの出力の性質上、非常に長い行がいくつかあるため (文字通り数百メガバイトの行もあります)、これは実行可能なオプションではないと思います。

適度なサイズのメモリ フットプリント (数十 MB など) を使用して、このファイルを読み取り、正規表現を使用してストリーム内で変更するにはどうすればよいでしょうか?

4

1 に答える 1

0
$chunk = $reader.read() //read in exactly $chunk_length characters from the file (or less iff EOF reached)
while (!end_of_file($reader)) {
    $previous_chunk = $chunk;
    $chunk = $reader.read() //read in $chunk_length characters from the file (or less iff EOF reached)

    $double_chunk = $previous_chunk + $chunk;
    // do regular expressions on the double chunk (to catch matches that span the chunk boundary)
    $previous_chunk = substr($double_chunk, 0, $chunk_length);
    $chunk = substr($double_chunk, $chunk_length);
    $output_file.write($previous_chunk);
}

// do regular expressions on $chunk to process the last one (or the first and only one)
$output_file.write($chunk);

問題1と2はどちらも、正規表現の置換を実行し、結果の文字列チャンクを$previous_chunkと$chunkに割り当てることで解決しました。ただし、置換文字列として使用しているものが一致を再トリガーしないと仮定します。これにより、writeが$ previous_chunkを使用するように変更され、チャンクスパンの一致をキャッチする次の機会に$chunkを変更できるようになります。

また重要なことに、上記は、置換が置換される文字列と同じ長さであることを前提としています。そうでない場合、チャンクサイズは置換後に動的に変化し、上記のソリューションは単純すぎて処理できません。置換文字列の長さが異なる場合は、チャンク境界の変化を何らかの方法で追跡する必要があります。

于 2013-01-16T18:10:15.040 に答える