Re: How to open a file from the end and read the last 100 lines

From: James Willmore (jwillmore_at_remove.adelphia.net)
Date: 12/07/03


Date: Sun, 07 Dec 2003 17:01:19 GMT

On Sun, 07 Dec 2003 03:37:47 GMT
"Mihai N." <nmihai_year_2000@yahoo.com> wrote:
> Uri Guttman <uri@stemsystems.com> wrote in
> news:x7brqlsao7.fsf@mail.sysarch.com:
> >>>>>> "AS" == Anno Siegel <anno4000@lublin.zrz.tu-berlin.de>
> >writes:
> > AS> Sara <genericax@hotmail.com> wrote in comp.lang.perl.misc:
> > >> anno4000@lublin.zrz.tu-berlin.de (Anno Siegel) wrote in
> > >message> news:<bqs8md$hfo$1@mamenchi.zrz.TU-Berlin.DE>...
> > >> > >
> > >> > > die "I hate MONDAYS!\n" unless open F, 'log';
> > >> > > my @l = <F>;
> > >> > > close F;
> > >> > > @l = splice @l, @l-100;
> > >> > >
> > >> > > and botta bing you have your last 100 lines!
> > >> >
> > >> > ...except when the file has fewer than 100 lines, in which
> > >case a> > fatal run-time error results. Uri's
> > >File::ReadBackwards deals> > correctly with that case.
> > >> >
> > >> > This is a good demonstration why "rolling your own" is a bad
> > >idea,> > even if the problem looks trivial.
> > >>
> > >> Oh yes a small mod for that trivial case:
> > >>
> > >> splice @l, @l-100 if @l > 100;
> >
> > AS> Don't shrug off trivial bugs. In a production program, this
> > AS> kind
> > of AS> bug can go unnoticed for a long time. Then the program
> > fails for no AS> good reason, perhaps because it's called a few
> > times a day instead of AS> just once. Not good. CPAN modules
> > don't *have* trivial bugs like that.
> >
> > and my module is much faster than her code as well. slurping in a
> > whole file to get last 100 lines is a waste of ram and cpu. and if
> > the file is a large log, forget it. sara will just have to learn
> > that rolling your own all the time is fruitless. the ultimate
> > result is write your own in c because perl is just a large c based
> > application.
> >
> > uri
> >
>
> what about this:
> while( <> ) {
> push @lines, $_;
> shift @lines if $#lines > 100;
> }
>
> I agree CPAN is great.
> But you have to put hings in balance.
>
> When the time + effort to search for what you need,
> evaluate the 20 possible modules, select one or two, compare,
> understand how they work, I would rather write my own two lines.
>
> I would not do this for complex stuff, like parsing XML/HTML,
> sending emails, DB interogations, etc.
> Where is the limit for "complex" for each one, it is for each
> one to decide. If I am not able to write a line of perl to
> do my stuff, chances are I will not be able to use properly a
> CPAN module.
> CPAN is not going to think for you.

If you *must* "roll your own", you might try this. However, read the
notes at the end of the code before using.

--untested--
#!/usr/bin/perl -w

#use strict pragma
use strict;

#get the filename of the file to process -
#die if no filename is provided
my $in_file = shift
        or die "No filename provided\n";
#open the file to process -
#die if it can't be opened
open(IN, $in_file)
        or die "Can't open $in_file: $!\n";
#read the file - in reverse - into an array
my @reverse = reverse <IN>;
#close the file
close IN;

#declare a counter
my $count = 0;
#declare an array to hold the lines we want
my @lines;
#while there is still an array
#containing the original file (in reverse) ...
while(@reverse){
        #increment the counter
        $count++;
        #push onto the array for the lines we want the
        #value of the current line - shift it from the
        #original file (in reverse) array
        push @lines, shift @reverse;
        #break the loop if we reach the amount of lines
        #from the end of the file (ie last 100 lines
        #of the original file)
        last if $count == 100;
}

#print the filnal results (ie last 100 lines of the file)
print reverse @lines;
--untested--

I tested (yes, I *always* put untested for the code, because IMHO it's
never tested enough) this with two files. One with 5 lines and my
messages file (which has well over 100 lines). It worked for both.
However, this method has some issues. First, if the file being read
exceeds the system memory, the script will most likely crap. It also
uses open versus sysopen.. And, there's no file locking. And, you
will most likely miss log messages if you use this againist an active
log file. There are propbably other issues with this method, but if
you want to use it instead of using a tested method, be my guest :-)

This was "quick and dirty" - so the quality is most likely below
standards.

HTH

-- 
Jim
Copyright notice: all code written by the author in this post is
 released under the GPL. http://www.gnu.org/licenses/gpl.txt 
for more information.
a fortune quote ...
"We have reason to believe that man first walked upright to free 
his hands for masturbation."   -- Lily Tomlin 


Relevant Pages

  • Re: Reversing Array Elements?
    ... Depends what you mean by "actually reverse the array". ... rather than a specification of the language. ... could make such a reordered copy in physical memory as an optimization. ...
    (comp.lang.fortran)
  • Re: Working with floating point numbers.
    ... mechanism but now need to reverse the situation and convert a double to the ... I have reversed the code but come stuck when I try to assign the array to ... I've tried to Asc) the string but it didn't work and when I ... Dim S As MyStrings ...
    (microsoft.public.access.modulesdaovba)
  • Re: reverse a collection
    ... indirectly you can leverage this method. ... similar methods, then you are correct, looping may be your only option. ... Array has a reverse method. ...
    (microsoft.public.dotnet.languages.vb)
  • Re: Cohens paper on byte order
    ... > you changed from a bit sequence to what appears to be ... an array of unsigned char to represent a bit array, ... in the reverse order instead? ... But the user input IS at the beginning a bit array ...
    (sci.crypt)
  • Re: with bash : hostname -d - with perl?
    ... I sought on CPAN but not with the good word ... (remove .invalid and reverse each component for email address) ... comp.lang.perl.misc guidelines on the WWW: ...
    (comp.lang.perl.misc)

Loading