Oh well, this question keeps popping up every few months. How do I tail a large file with perl? Here is my crack at it, it uses seek from the end of the file. Linux only for now. Bill Gates dosn't seem to care about linux compatibility, so why should I care about windows compatibility?
#!/usr/bin/perl -w # Simple program to read the last n line(s) of a file. # Reads from the end of the file for effeciency # "\n" linux only, # usage tailz filename numberoflines use strict; my $filename = shift or die "Usage: $0 file numlines\n"; my $numlines = shift; my $byte; # Open the file in read mode open FILE, "<$filename" or die "Couldn't open $filename: $!"; # Rewind from the end of the file until count of eol 's seek FILE,-1, 2; #get past last eol my $count=0; while (1){ seek FILE,-1,1; read FILE,$byte,1; if(ord($byte) == 10 ){$count++;if($count == $numlines){last}} seek FILE,-1,1; if (tell FILE == 0){last} } $/=undef; my $tail = <FILE>; print "$tail\n";

Replies are listed 'Best First'.
•Re: pure perl tail
by merlyn (Sage) on Sep 06, 2002 at 20:41 UTC

      Minor comment, not meant to start an argument:  I don't think it's necessary to always look to use a perl module as your comment, merlyn, seems to imply.  Of course, if one is floundering with a task, look for a module.  But if one can pull a task off without much trouble, then I think one should try to create one's own code if for no other reason than for the experience.  zentara doesn't seem to be knocking modules with the "pure perl" reference--I think he's trying to avoid system calls since that may feel like cheating sometimes--so there's no need to knock his code.

      Having said all that, zentara, buddy, listen to merlyn and use the File::Tail module and get on with your life.  There are more interesting fish tails to fry.

      -Spenser

      That's Spenser, with an "s" like the detective.

        Reinventing the wheel to learn is fine, but don't assume the wheel has yet to be invented.

        --
        perl -pew "s/\b;([mnst])/'$1/g"

Re: pure perl tail
by belg4mit (Prior) on Sep 06, 2002 at 21:51 UTC
    Or even tail.

    Some of the things you could do better, use /\r?\n|\r/ to check EOL. Use perl -l, don't undef $/, and don't print a newline. Have you considered a pipe?

    --
    perl -pew "s/\b;([mnst])/'$1/g"

Re: pure perl tail
by zentara (Cardinal) on Sep 07, 2002 at 16:04 UTC
    Well, to respond to Merlyn, I started thinking about how to do it after reading a reply he wrote on clpm that File::Backwards and Tie::File are good, but not quite the fastest. So I thought, hmmm, how would I do this? The code is the most straight forward approach I could come up with. Just start at the EOF and count back byte by byte, counting newlines, until I satified my $numlines test. I tested it against the following File::Backwards script on a 100 meg file, and my script was faster by a small amount, plus I don't need to use a module. I used the system time command to time them.
    #!/usr/bin/perl use File::ReadBackwards; #usage tailfilebackwards filename numlines my $filename = shift or die "Usage: $0 file numlines\n"; my $numlines = shift; $bw = File::ReadBackwards->new($filename) or die "can't read $filename $!" ; $count=0; while(defined($line = $bw->readline)){ push @lines,$line ; $count++; if ($count == $numlines){last} } @lines= reverse @lines; print "@lines\n"; exit;
    My sample times follow:
    For 3 tries -> time tailfilebackwards ARCHIVE 10
    real    0m0.078s
    user    0m0.040s
    sys     0m0.010s
    
    real    0m0.060s
    user    0m0.040s
    sys     0m0.010s
    
    real    0m0.077s
    user    0m0.040s
    sys     0m0.000s
    ###########################################################
    For 3 tries -> time tailz ARCHIVE 10
    
    real    0m0.051s
    user    0m0.010s
    sys     0m0.000s
    
    real    0m0.056s
    user    0m0.010s
    sys     0m0.010s
    
    real    0m0.056s
    user    0m0.010s
    sys     0m0.020s
    ##########################################################
    
    Now I admit that my method is non-portable, so the modular methods are better in that respect, but time-wise they are not. If anyone cares to comment on how I might make my method better, I would appreciate that.
      Wow..This is g8...i always believe that i must have full control on what i am coding...predefined modules are good but not ever...they definitely contains "extra" code which is not required by us and in large projects it "MATTERS".
Re: pure perl tail
by Aristotle (Chancellor) on Sep 07, 2002 at 19:24 UTC
    Why are you using binmode if the code is meant as Linux only, anyway?

    Makeshifts last the longest.