views:

175

answers:

2

I am working on a log parsing script using Perl. I am reading the log file as follows:

open(LOGFILE, "$logFile") || die "Error opening log file $logFile\n";         
while(<LOGFILE>) 
{   
  #Processing statements goes here.
}

Now in processing statements I want to check if the file reading pointer is on the last line. if yes then want to process a condition before exiting.

So the question is from within the while loop which is being used to read the file line by line, How do I find out if it's on the last line?

+5  A: 
my $last;
while(<MYFILE>) {
   $last = $_ if eof;
}

Though unless you are doing something with every other line, this is pretty inefficient.

butterchicken
@butterchicken. Thanks. Tried "print $last = $_ if eof;" and could print last line of the file.
Viky
@butterchicken. Can i use this in a plain if condition.something like if(to check eof )
Viky
+1. @butterchiken. if(eof) is working fine. Thanks for your prompt reply.
Viky
NPs; yes, eof can work inside an IF - but you got there on your own :)
butterchicken
+4  A: 

If you only care about the last line, take a look at File::ReadBackwards. It was specifically designed for logfiles and situations where the items of interest are at the end.

Once you install that module, you can pop off the last line only (rather than going through the whole file until it's found) quite easily:

#!/usr/bin/env perl
use strict;
use warnings;
use File::ReadBackwards;

my $fh = File::ReadBackwards->new( 'dir_walk.rb' )
    or die "Can't read 'dir_walk.rb': $!";

my $last_line = $fh->readline;

print $last_line;

Edit: For what it's worth, I would only recommend this if you don't want to look through the whole file. That is, if you are going to read through the entire file no matter what, then this is probably not the best solution. (I am not quite sure from your question whether you only want to check for a specific item in the last line, or if you also care about the rest of the log.)

Telemachus
+1 I believe he wants to process the whole file anyway and treat the last line specially. There will probably be a performance impact from doing it backwards although it should not be significant for small files.
Sinan Ünür
@Sinan: I couldn't quite tell if he did or didn't want to process the whole log or not. I tend to think that if he _does_ want to deal with the whole file, then this is _not_ the best solution. I'll add a note to that effect.
Telemachus
@Telemachus I tried it with 1 MB files ... not a huge difference at all. Then I tried it with 80 MB files 2 seconds versus 10 seconds. ;-)
Sinan Ünür
@Sinan, @Telemachus. Here's the deal. I want to parse/Process the whole log file line by line and keep matching a pattern. If the pattern matches I do some processing. Now i am not immediately processign when the pattern matches coz i check for how many consequtive times the pattern matches and then process it.So while the file reading is on last line, I wanted to be able to track that and do the previous processing. hope that clears what I wanted to achieve.
Viky