У меня есть файл с именем $dir
и строка с именем $line
, я знаю, что эта строка является полной строкой этого файла, но я не знаю его номер строки, и я хочу удалить ее из файла, что мне делать?
Можно ли использовать awk?
$contents = file_get_contents($dir); $contents = str_replace($line, '', $contents); file_put_contents($dir, $contents);
Прочитайте строки один за другим и напишите все, кроме строки соответствия, в другой файл. Затем замените исходный файл.
это будет просто просматривать каждую строку, и если это не то, что вы хотите удалить, оно попадает в массив, который будет записан обратно в файл. видеть это
$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);
Другой подход заключается в том, чтобы прочитать файл строки за строкой, пока не найдете совпадение, затем обрезайте файл до этой точки, а затем добавьте остальные строки.
Это также хорошо, если вы ищете подстроку (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, студент»
Старый файл:
ID, род занятий
123, студент
124, кирпичный слой
Запуск кода изменит файл на:
Новый файл:
ID, род занятий
124, кирпичный слой
Как это:
file_put_contents($filename, str_replace($line . "\r\n", "", file_get_contents($filename)));
Я думаю, что лучший способ работать с файлами – редактировать их как строки.
Во-первых, получите все строки файла (следующие коды можно сжать):
$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 (eg $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 () не сможет ее найти).
Его можно решить без использования 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); }