Delete first lines after file append - php

I use append code to write new lines in .txt file:
$fh = fopen('ids.txt', 'a');
fwrite($fh, "Some ID\n");
fclose($fh);
I want this file to have only 20 lines and delete the first (old) ones.

Read all the lines in, add your lines at the bottom, then rewrite the file with only the last 20 lines.

I am not great at php, but if you only want 20 lines surely you would do something like this pseudocode.
lines <- number of lines you want to write
if lines > 20
yourfile <- new file
yourfile.append (last 20 lines of your text)
else if lines = 20
your file <- new file
yourfile.append (your text)
else
remainingtext <- the last [20-lines] of yourfile
yourfile.append (remaining text + your text)
EDIT: an easier way of doing it, but perhaps less efficient [I think this is equivalent to NovaDenizen's solution]
yourfile <- your file
yourfile.append(yourtext)
newfilearray <- yourfile.tokenize(newline)(http://php.net/manual/en/function.explode.php)
yourfile <- newfile
for loop from i=newfilearray.size-21 < newfilearray.size
yourfile.append (newfilearray[i])

$content=file($filename);
$content[]='new line of content';
$content[]='another new line of content';
$file_content=array_slice($content,-20,20);
$file_content=implode("\n",$file_content);
file_put_contents($filename,$file_content);
You can us file() function to load file as an array. Then add new content to loaded array, slice it to 20 elements, make 'entered' text from this array and save it to a file.

You could make use of the function file:
http://php.net/manual/en/function.file.php
Reads an entire file into an array.
This said, you Need to do the following:
1.) Read the existing file into an Array:
$myArray= file("PathToMyFile.txt");
2.) Reverse the Array, so the oldest Entry is topmost:
$myArray= array_reverse($myArray);
3.) Add your NEW Entry to the end of that Array.
$myArray[] = $newEntry + "\n";
4.) Reverse it again:
$myArray= array_reverse($myArray);
5.) Write the first 20 Lines back to your file (this is your "new" + 19 old lines):
$i = 1;
$handle = fopen("PathToMyFile.txt", "w"); //w = create or start from bit 0
foreach ($myArray AS $line){
fwrite($handle, $line); //line end is NOT removed by file();
if ($i++ == 20){
break;
}
}
fclose($handle);

Why dont you just use file_put_contents("yourfile.txt", ""); to set the file contents to nothing and then just file_put_contents("yourfile.txt",$newContent)?
Are you trying to do something else or am I missing something?

Related

Removing A Specific Line From A File

I have a text file like this:
1
2
3
4
5
6
7
8
9
10
And I want to remove specific lines which numbers are in an array like this:
$myfile='txt.txt';
$remove=array(1,3,6,7,10);
//wanna remove these lines
So I tried this code but It didn't work and It just doubles the text and ruins everything:
<?php
$myfile='txt.txt';
$remove=array(1,3,5,7,10);
$lines=file($myfile);
$countline=sizeof($lines);
$data=file_get_contents($myfile);
for ($i=0; $i < $countline+1; $i++) {
if (in_array($i, $remove)) {
$editeddata=str_replace($lines[$i], "", $data);
$removeline = file_put_contents($myfile, $editeddata.PHP_EOL , FILE_APPEND | LOCK_EX);
}
}
?>
I couldn't use ((for)) properly and I think it will just ruin the text because it deletes lines one after another have been deleted and it changes the order so I should have a code to remove them all at once.
And please don't give a code to just replace numbers because the main text file is not only numbers and contains word,etc...
Thanks A lot!
You're reading the file twice (with file and file_get_contents), which I think is confusing the later code. You have everything you need with the first call - an array of all the lines in the file. You're also using str_replace to remove the content, which seems a bit dangerous if any of the content is repeated.
I'd refactor this to simply filter the array of lines based on their line-number, then write it back to the file in a single operation:
$myfile = 'txt.txt';
$remove = [1, 3, 5, 7, 10];
// Read file into memory
$lines = file($myfile);
// Filter lines based on line number (+1 because the array is zero-indexed)
$lines = array_filter($lines, function($lineNumber) use ($remove) {
return !in_array($lineNumber + 1, $remove);
}, ARRAY_FILTER_USE_KEY);
// Re-assemble the output (the lines already have a line-break at the end)
$output = implode('', $lines);
// Write back to file
file_put_contents($myfile, $output);
If the file fits in memory then you can do the simple:
$myfile='txt.txt';
$remove=array(1,3,6,7,10);
file_put_contents($myfile, implode(PHP_EOL,array_diff($file($myfile,FILE_IGNORE_NEW_LINES), $remove)));
Note: Because it's a bit ambiguous whether $remove has the content or the lines you want to remove, the above code removes the content . If you want to remove lines change array_diff($file($myfile,FILE_IGNORE_NEW_LINES), $remove) to array_diff_keys($file($myfile,FILE_IGNORE_NEW_LINES), array_flip($remove))
If your file is large then you need to resort to some sort of streaming. I suggest against reading and writing to the same file and doing something like:
$myfile='txt.txt';
$remove=array(1,3,6,7,10);
$h = fopen($myfile,"r");
$tmp = fopen($myfile.".tmp", "w");
while (($line = fgets($h)) !== false) {
if (!in_array(rtrim($line, PHP_EOL), $remove)) {
fwrite($tmp, $line);
}
}
fclose($h);
fclose($tmp);
unlink($myfile);
rename($myfile.".tmp", $myfile);

How to append text to a file a 15 lines above its end

I am trying add HTML to a file using fwrite(). My final goal is to get it to add it 15 lines above the end of the file. Here is what I have so far:
<?php
$file = fopen("index.html", "r+");
// Seek to the end
fseek($file, SEEK_END, 0);
// Get and save that position
$filesize = ftell($file);
// Seek to half the length of the file
fseek($file, SEEK_SET, $filesize + 15);
// Write your data
$main = <<<MAIN
//html goes here
MAIN;
fwrite($file, $main);
// Close the file handler
fclose($file);
?>
This just keeps overwriting the top of the file.
Thanks.
The sample code in the question does not operate based on lines, since you're working with file size (unless there is an assumption about definition of lines in the application that is not mentioned in here). If you want to work with lines, then you'd need to search for new line characters (which separates each line with the next).
If the target file is not a large file (so we could load the whole file into memory), we could use PHP built-in file() to read all the lines of the file into an array, and then insert the data after the 15th element. something like this:
<?php
$lines = file($filename);
$num_lines = count($lines);
if ($num_lines > 15) {
array_splice($lines, $num_lines - 15, 0, array($content));
file_put_contents($filename, implode('', $lines));
} else {
file_put_contents($filename, PHP_EOL . $content, FILE_APPEND);
}

Remove line containing X & 20 lines above

I have a large text file I am trying to sort.
I need to:
Search for lines that contain 'No'
Delete this line and 28 lines above it
The document contains 6,1711 lines hence me looking for a quick way to do it.
Tried using Notepad++ but cant seem to be able to select the 28 lines above to also delete.
Any help would be greatly appreciated.
Thanks,
here's something to work on, read file into an Array loop through each line while incrementing index and 20 lines before it then save to new document the array.
//read file into string array
$filelines = file('Filelocation.txt');
$i = 0;
foreach ($filelines as $line => $filelines)
{
if (strpos($line,'No') !== false)
{
$j = $i
while ($j > $i - 20) {
unset($filelines[j]);
$j--
}
}
$i++;
}
//Save Whatever is left into new file
print($filelines)
How about:
Find what: (.+\R){28}.*\bNo\b.*\R
Replace with: Nothing
Make sure you've checked Regular Expression and NOT dot includes newline
If you want to restrict the search, you could use:
Find what: (.+\R){28}.*\bemails: No\b.*\R
Or every string that's more significant.

PHP file write - max lines

How to put a limit for writing in a file, if it hit the limit then remove the last line..
As example here's a file:
Line 3
Line 2
Line 1
i want to max line it for 3 lines only.. so when i write a new line using any append functions it removes the last line.. Let's say i just wrote a new line ( Line 4 ).. so it goes to the last one and remove it, result should be :
Line 4
Line 3
Line 2
And for a new written line (Line 5):
Line 5
Line 4
Line 3
numeric lines is not required, i just want to remove the last line if there's a new added line via an append functions (file_put_contents / fwrite) and max it by 3 or a specific number i give
You can try
$max = 3;
$file = "log.txt";
addNew($file, "New Line at : " . time());
Function Used
function addNew($fileName, $line, $max = 3) {
// Remove Empty Spaces
$file = array_filter(array_map("trim", file($fileName)));
// Make Sure you always have maximum number of lines
$file = array_slice($file, 0, $max);
// Remove any extra line
count($file) >= $max and array_shift($file);
// Add new Line
array_push($file, $line);
// Save Result
file_put_contents($fileName, implode(PHP_EOL, array_filter($file)));
}
Here's one way:
Use file() to read the file's lines into an array
Use count() to determine if there's more than 3 elements in the array. If so:
Remove the last element of the array with array_pop()
Use array_unshift() to add an element (the new line) to the front of the array
Overwrite the file with the lines of the array
Example:
$file_name = 'file.txt';
$max_lines = 3; #maximum number of lines you want the file to have
$new_line = 'Line 4'; #content of the new line to add to the file
$file_lines = file($file_name); #read the file's lines into an array
#remove elements (lines) from the end of the
#array until there's one less than $max_lines
while(count($file_lines) >= $max_lines) {
#remove the last line from the array
array_pop($file_lines);
}
#add the new line to the front of the array
array_unshift($file_lines, $new_line);
#write the lines to the file
$fp = fopen($file_name, 'w'); #'w' to overwrite the file
fwrite($fp, implode('', $file_lines));
fclose($fp);
Try this.
<?php
// load the data and delete the line from the array
$lines = file('filename.txt');
$last = sizeof($lines) - 1 ;
unset($lines[$last]);
// write the new data to the file
$fp = fopen('filename.txt', 'w');
fwrite($fp, implode('', $lines));
fclose($fp);
?>
Modified from Baba's answer; this code will write the new line at the beginning of the file and will errase the last one to keep always 3 lines.
<?php
function addNew($fileName, $line, $max) {
// Remove Empty Spaces
$file = array_filter(array_map("trim", file($fileName)));
// Make Sure you always have maximum number of lines
$file = array_slice($file, 0, --$max);
// Remove any extra line and adding the new line
count($file) >= $max and array_unshift($file, $line);
// Save Result
file_put_contents($fileName, implode(PHP_EOL, array_filter($file)));
}
// Number of lines
$max = 3;
// The file must exist with at least 2 lines on it
$file = "log.txt";
addNew($file, "New Line at : " . time(), $max);
?>

How to split content into equal parts then write to file in PHP

I have been reading/testing examples since last night, but the cows never came home.
I have a file with (for example) approx. 1000 characters in one line and want to split it into 10 equal parts then write back to the file.
Goal:
1. Open the file in question and read its content
2. Count up to 100 characters for example, then put a line break
3. Count 100 again and another line break, and so on till it's done.
4. Write/overwrite the file with the new split content
For example:
I want to turn this => KNMT2zSOMs4j4vXsBlb7uCjrGxgXpr
Into this:
KNMT2zSOMs
4j4vXsBlb7
uCjrGxgXpr
This is what I have so far:
<?php
$MyString = fopen('file.txt', "r");
$MyNewString;
$n = 100; // How many you want before seperation
$MyNewString = substr($MyString,0,$n);
$i = $n;
while ($i < strlen($MyString)) {
$MyNewString .= "\n"; // Seperator Character
$MyNewString .= substr($MyString,$i,$n);
$i = $i + $n;
}
file_put_contents($MyString, $MyNewString);
fclose($MyString);
?>
But that is not working quite the way I anticipated.
I realize that there are other similiar questions like mine, but they were not showing how to read a file, then write back to it.
<?php
$str = "aonoeincoieacaonoeincoieacaonoeincoieacaonoeincoieacaonoeincoieacaon";
$pieces = 10;
$ch = chunk_split($str, $pieces);
$piece = explode("\n", $ch);
foreach($piece as $line) {
// write to file
}
?>
http://php.net/manual/en/function.chunk-split.php
Hold on here. You're not giving a file name/path to file_put_contents();, you're giving a file handle.
Try this:
file_put_contents("newFileWithText.txt", $MyNewString);
You see, when doing $var=fopen();, you're giving $var a value of a handle, which is not meant to be used with file_put_contents(); as it doesnt ask for a handle, but a filename instead. So, it should be: file_put_contents("myfilenamehere.txt", "the data i want in my file here...");
Simple.
Take a look at the documentation for str_split. It will take a string and split it into chunks based on length, storing each chunk at a separate index in an array that it returns. You can then iterate over the array adding a line break after each index.

Categories