tags:

views:

138

answers:

6

Hi there,

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.

+4  A: 

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.

SimpleCoder
Hi SimpleCoder, thank you very much for your response and your efforts! I've tried out your code and it works flawlessly and keeps the line structure. Thanks for your reply. ;)
AUllah1
You're welcome, I'm glad I could help!
SimpleCoder
+3  A: 

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.

oneat
Hi oneat, thank you very much for your reply. I've tried out your coding and it seems pretty efficient, however it displays errors when I use it. I believe it said on line 2, empty variable. Of course, I'm pretty sure that it was an error on my end. Again, thank you very much for your time and efforts, they are extremely appreciated. ;)
AUllah1
+5  A: 

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";
}
Sabeen Malik
Hi Sabeen Malik, thank you for your reply and your effort. I am really grateful of it. When I used the code, I believe it said on line 2, empty variable. Of course, I'm pretty sure that it was an error on my end. Again, thank you very much for your time and efforts, they are extremely appreciated. ;)
AUllah1
I am glad i was of use. The $content variable needs to carry the data in your file, the $newContent variable at the end will carry the new stripped file and can be written to a new file.
Sabeen Malik
+4  A: 

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.

codaddict
+1 Only suitable answer and exactly what I'd do myself.
hopeseekr
Hi codaddict, thanks for your reply and effort, I am really grateful of it. Your coding seems amazing and pretty efficent, however when I attempted to use your code, it emptied out the whole text file, leaving it blank. I'm not too sure where the problem may have occurred, of course I'm pretty sure it was probably me not doing something right. :( Again, thank you for your response and I do extremely appreciate your effort, reply and time. ;)
AUllah1
Make sure you are not opening your input file in write mode. If you do so it'll wipe out its content!!
codaddict
My program reads the input file and creates a new output file with the unwanted lines removed. So make sure you've different filenames for input and output.
codaddict
+6  A: 
file_put_contents($newfile, 
    implode(
        preg_grep('~^[1-9]~', 
            file($oldfile))));

php is not particularly elegant, but still...

stereofrog
+1 That's awesome!
hopeseekr
Hi stereofrog, thank you very much for your response and effort. I am grateful that you replied. I am extremely fond of the method that you used, by only accepting those which start with 1 or 9. Again, thank you for your response as well as effort! Thank you. ;)
AUllah1
A: 

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.

GZipp