ファイルの特定の行を上書きする最良の方法は何ですか? 基本的に、ファイルで文字列「@parsethis」を検索し、その行の残りを別のもので上書きしたいと考えています。
7 に答える
If the file is really big (log files or something like this) and you are willing to sacrifice speed for memory consumption you could open two files and essentially do the trick Jeremy Ruten proposed by using files instead of system memory.
$source='in.txt';
$target='out.txt';
// copy operation
$sh=fopen($source, 'r');
$th=fopen($target, 'w');
while (!feof($sh)) {
$line=fgets($sh);
if (strpos($line, '@parsethis')!==false) {
$line='new line to be inserted' . PHP_EOL;
}
fwrite($th, $line);
}
fclose($sh);
fclose($th);
// delete old source file
unlink($source);
// rename target file to source file
rename($target, $source);
あなたの主な問題は、新しい行が古い行と同じ長さではない可能性があるという事実です。行の長さを変更する必要がある場合、少なくとも変更された行の後のファイル全体を書き換える方法はありません。最も簡単な方法は、変更した新しいファイルを作成し、それを元のファイルの上に移動することです。このようにして、読者はいつでも完全なファイルを利用できます。ロックを使用して、一度に 1 つのスクリプトだけがファイルを変更するようにします。ファイルを置き換えるので、別のファイルでロックを行います。チェックアウトしてくださいflock()
。
新しい行が古い行と同じ長さになることが確実な場合は、ファイルを読み取り/書き込みモードで開き (r+
の 2 番目の引数として使用fopen()
)、 を呼び出しftell()
て、各回の行の開始位置を保存してから、fgets()
行を読むために呼び出します。上書きしたい行が見つかったら、 を使用して行の先頭と新しいデータfseek()
に戻ることができます。fwrite()
行が常に同じ長さになるように強制する 1 つの方法は、可能な最大長になるまでスペースを埋めることです。
または、ファイルが大きすぎない場合:
$sample = file_get_contents('sample');
$parsed =preg_replace('#@parsethis.*#', 'REPLACE TO END OF LINE', $sample);
ただし、ファイルに存在しない区切り文字「#」を選択する必要があります。
私はジェレミーが提案したことをする可能性が最も高いですが、ここでそれを行う別の方法は別の解決策です。これはテストも使用もされておらず、*nix システム用です。
$cmd = "grep '@parsethis' " . $filename;
$output = system($cmd, $result);
$lines = explode("\n", $result);
// Read the entire file as a string
// Do a str_repalce for each item in $lines with ""