$dir
という名前のファイルと$line
という名前の文字列があります。この文字列はそのファイルの完全な行であることはわかっていますが、行番号がわからないので、ファイルから削除します。私は何をすべきか?
Awkを使用することは可能ですか?
$contents = file_get_contents($dir);
$contents = str_replace($line, '', $contents);
file_put_contents($dir, $contents);
行を1つずつ読み取り、一致する行を除くすべてを別のファイルに書き込みます。次に、元のファイルを置き換えます。
これはすべての行を調べ、削除したくない場合は、ファイルに書き戻される配列にプッシュされます。 これを参照
$DELETE = "the_line_you_want_to_delete";
$data = file("./foo.txt");
$out = array();
foreach($data as $line) {
if(trim($line) != $DELETE) {
$out[] = $line;
}
}
$fp = fopen("./foo.txt", "w+");
flock($fp, LOCK_EX);
foreach($out as $line) {
fwrite($fp, $line);
}
flock($fp, LOCK_UN);
fclose($fp);
別のアプローチは、一致が見つかるまでファイルを1行ずつ読み取り、そのポイントまでファイルを切り捨て、残りの行を追加することです。
Awkを使用せずに解決できます。
function remove_line($file, $remove) {
$lines = file($file, FILE_IGNORE_NEW_LINES);
foreach($lines as $key => $line) {
if($line === $remove) unset($lines[$key]);
}
$data = implode(PHP_EOL, $lines);
file_put_contents($file, $data);
}
これは、行で部分文字列(ID)を探していて、古い行を新しい行に置き換えたい場合にも適しています。
コード:
$contents = file_get_contents($dir);
$new_contents= "";
if( strpos($contents, $id) !== false) { // if file contains ID
$contents_array = preg_split("/\\r\\n|\\r|\\n/", $contents);
foreach ($contents_array as &$record) { // for each line
if (strpos($record, $id) !== false) { // if we have found the correct line
pass; // we've found the line to delete - so don't add it to the new contents.
}else{
$new_contents .= $record . "\r"; // not the correct line, so we keep it
}
}
file_put_contents($dir, $new_contents); // save the records to the file
echo json_encode("Successfully updated record!");
}
else{
echo json_encode("failed - user ID ". $id ." doesn't exist!");
}
例:
入力: "123、student"
古いファイル:
ID、職業
123、学生
124、レンガ層
コードを実行すると、ファイルが次のように変更されます。
新しいファイル:
ID、職業
124、レンガ層
テキストを配列に変換し、最初の行を削除してテキストに再変換します
$line=explode("\r\n",$text);
unset($line[0]);
$text=implode("\r\n",$line);
ファイルを扱う最良の方法は、ファイルを文字列として編集することだと思います。
まず、ファイルのすべての行を取得します(次のコードは圧縮できます)。
$file = @fopen($dir, 'r'); # As you said, $dir is your filename
if ($file) { # Ending bracket is at the end
if (filesize($dir)) { # Checks whether the file size is not zero (we know file exists)
$fileContent = fread($file, filesize($dir)); # Reads all of the file
fclose($file);
} else {
// File is empty
exit; # Stops the execution (also you can throw an exception)
}
$fileLineByLine = explode(PHP_EOL, $fileContent); # Divides the file line by line
ここでは、検索を実行できます。
$key = false; # By default, your string $line is not in the file (false)
foreach ($fileLineByLine as $lineNumber => $thisLine)
if ($thisLine === $line)
$key = $lineNumber; # If $line found in file, set $key to this line number
単純に、行$ key + 1を削除できます。
if ($key !== false) # If string $line found in the file
unset($fileLineByLine[$key]); # Remove line $key + 1 (e.g. $key = 2, line 3)
最後に、変更をファイルに保存する必要があります。
$newFileContent = implode(PHP_EOL, $fileLineByLine); # Joins the lines together
$file = fopen($dir, "w"); # Clears the file
if ($file) {
fwrite($file, $newFileContent); # Saves new content
fclose($file);
}
} # Ends 'if ($file) {' above
また、上記のコードを関数として設定することもできます。
メモ:
$ lineには、\ nのような改行文字があってはなりません。それらを削除する必要があります。
$line = str_replace(PHP_EOL, '', $line);
使わない
$fileLineByLine[$key] = "";
の代わりに
unset($fileLineByLine[$key]);
最初のケースは行を削除しないため、行をクリアするだけです(そして不要な空行が残ります)。その場合、implode()は空の$ fileLineByLine [$ key]にも新しい行を追加します。そうしないと、変数の設定を解除すると使用できなくなります(そして、implode()はそれを見つけることができません)。
このような:
file_put_contents($filename, str_replace($line . "\r\n", "", file_get_contents($filename)));