I have a file named $dir
and a string named $line
, I know that this string is a complete line of that file but I don't know its line number and I want to remove it from file, what should I do?
Is it possible to use awk?
I have a file named $dir
and a string named $line
, I know that this string is a complete line of that file but I don't know its line number and I want to remove it from file, what should I do?
Is it possible to use awk?
$contents = file_get_contents($dir);
$contents = str_replace($line, '', $contents);
file_put_contents($dir, $contents);
Read the lines one by one, and write all but the matching line to another file. Then replace the original file.
this will just look over every line and if it not what you want to delete, it gets pushed to an array that will get written back to the file. see this
$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);
Another approach is to read the file line by line until you find a match, then truncate the file to that point, and then append the rest of the lines.
This is also good if you're looking for a substring (ID) in a line and want to replace the old line with the a new line.
Code:
$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!");
}
Example:
input: "123,student"
Old file:
ID,occupation
123,student
124,brick layer
Running the code will change file to:
New file:
ID,occupation
124,brick layer
It can be solved without the use of 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);
}
Like this:
file_put_contents($filename, str_replace($line . "\r\n", "", file_get_contents($filename)));
I think the best way to work with files is to edit them as strings.
First, get all lines of the file (the following codes can be compressed):
$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
Here, you can perform your search:
$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
Simply, you can remove line $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)
At last, you must save your changes to the file:
$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
Also you can set above code as a function.
Notes:
$line must not have new line characters like \n. You must remove them:
$line = str_replace(PHP_EOL, '', $line);
Don't use
$fileLineByLine[$key] = "";
instead of
unset($fileLineByLine[$key]);
because the first case doesn't remove the line, it just clears the line (and an unwanted empty line will remain). In that case, implode() adds a new line also for $fileLineByLine[$key] which is empty; otherwise if you unset a variable, it will unavailable (and implode() can not find it).