Remove line containing X & 20 lines above - php

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.

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);

Insert string to PDF with For loop

I'm a junior PHP developer.
For a costumer I need to place some strings into a pdf. I'm using FPDI and I like it.
I have an existing template PDF and I need to insert every characters of a string into a little graphic box (see image).
Every characters must have 2 millimeters (8px approximately) from each others.
Every strings can have different length, so I thought do like this:
$name = 'namenamename';
$stringcount = strlen($name)-1;
$countspace = $stringcount*2;
//121 = coordinate of first box
for ($x=121; $x <= $x+$countspace; $x = $x+2) {
for ($i=0; $i <= $stringcount; $i++) {
$pdf->SetXY($x, 37);
$pdf->Write(0,$name[$i]);
}
}
That doesn't work. This is the error:
Maximum execution time of 30 seconds
Can you help me please with the correct approach and with good explanation for a newbie? :)
Try this code:
$name = 'namenamename';
$string_length = strlen($name);
$coordinate = 121; //Give to the variable coordinate the beginning value, in this case 121
for ($i=0; $i < $string_length; $i++){ //make only one loop for the string length so the loop ends when there is no more characters
$char = substr($name,$i,1); // this is "the tricky part", with substr you can grab each character with its position in the string
$pdf -> SetXY($coordinate, 37); // here you put the coordinate for the character
$pdf -> Write(0, $char); // write it
$coordinate += 2; // and increment it by two, since the character are two spaces away from each other
}
hope that will help..
Maybe not a great solution but you can modify the execution time with this line of code
set_time_limit ( $seconds );
Anyway give it a try but i think that is more an error in the logic of the loop maybe.
Can you say exactly the coordinate where you need the two first characters, the first is 121 + something or 121?

Delete first lines after file append

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?

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.

PHP to delete lines within text file beginning with 0 or a negative number

Thank you for taking the time to read this and I will appreciate every single response no mater the quality of content. :)
Using php, I'm trying to create a script which will delete several lines within a text file (.txt) if required, based upon whether the line starts with a 0 or a negative number. Each line within the file will always start with a number, and I need to erase all the neutral and/or negative numbers.
The main part I'm struggling with is that the content within the text file isn't static (e.g. contain x number of lines/words etc.) Infact, it is automatically updated every 5 minutes with several lines. Therefore, I'd like all the lines containing a neutral or negative number to be removed.
The text file follows the structure:
-29 aullah1
0 name
4 username
4 user
6 player
If possible, I'd like Line 1 and 2 removed, since it begins with a neutral/negative number. At points, there maybe times when there are more than two neutral/negative numbers.
All assistance is appreciated and I look forward to your replies; thank you. :) If I didn't explain anything clearly and/or you'd like me to explain in more detail, please reply. :)
Thank you.
Example:
$file = file("mytextfile.txt");
$newLines = array();
foreach ($file as $line)
if (preg_match("/^(-\d+|0)/", $line) === 0)
$newLines[] = chop($line);
$newFile = implode("\n", $newLines);
file_put_contents("mytextfile.txt", $newFile);
It is important that you chop() the newline character off of the end of the line so you don't end up with empty space. Tested successfully.
Something on these lines i guess, it is untested.
$newContent = "";
$lines = explode("\n" , $content);
foreach($lines as $line){
$fChar = substr($line , 0 , 1);
if($fChar == "0" || $fChar == "-") continue;
else $newContent .= $line."\n";
}
If the file is big, its better to read it line by line as:
$fh_r = fopen("input.txt", "r"); // open file to read.
$fh_w = fopen("output.txt", "w"); // open file to write.
while (!feof($fh_r)) { // loop till lines are left in the input file.
$buffer = fgets($fh_r); // read input file line by line.
// if line begins with num other than 0 or -ve num write it.
if(!preg_match('/^(0|-\d+)\b/',$buffer)) {
fwrite($fh_w,$buffer);
}
}
fclose($fh_r);
fclose($fh_w);
Note: Err checking not included.
file_put_contents($newfile,
implode(
preg_grep('~^[1-9]~',
file($oldfile))));
php is not particularly elegant, but still...
Load whole line into variable trim it and then check if first letter is - or 0.
$newContent = "";
$lines = explode("\n" , $content);
foreach($lines as $line){
$fChar = $line[0];
if(!($fChar == '0' || $fChar == '-'))
$newContent .= $line."\n";
}
I changed malik's code for better performance and quality.
Here's another way:
class FileCleaner extends FilterIterator
{
public function __construct($srcFile)
{
parent::__construct(new ArrayIterator(file($srcFile)));
}
public function accept()
{
list($num) = explode(' ', parent::current(), 2);
return ($num > 0);
}
public function write($file)
{
file_put_contents($file, implode('', iterator_to_array($this)));
}
}
Usage:
$filtered = new FileCleaner($src_file);
$filtered->write($new_file);
Logic and methods can be added to the class for other stuff, such as sorting, finding the highest number, converting to a sane storage method such as csv, etc. And, of course, error checking.

Categories