Last 100 lines in a file

Yesterday, I had to pick out the last 100 lines in a file, for a small log viewer I was writing. Neither the Perl FAQ nor the Perl Cookbook had quite the right answer. So, this is what I ended up with.

sub last_lines {
  my ( $fh, $howmany ) = @_;
  my ( @lines, $i );
  while ( <$fh> ) {
    $lines[ $i++ ] = $_;
    $i = 0 if $i == $howmany;
  return grep { defined }
    @lines[ $i .. $howmany - 1 ], @lines[ 0 .. $i - 1 ];

This is reasonably memory efficient, more so than the example I found which read the entire file in and then just picked the last $howmany items from the array.

The last line is interesting. We have to “swivel” the array around a partition point, in order to get the entries into the correct order. Also, we have to get rid of undefined entries. These crop up if you have less than $howmany lines in the file.