sub print_trailing_lines { my $file = shift(); # file to read my $num_lines = shift(); # number of lines to grab my $block_size = shift() || 1024; # size of blocks to slurp my @lines = (); #array of lines open(FILE, "<$file") or die "could not open $file for reading: $!"; seek(FILE, -$block_size, 2); # go to the end, minus a block while ($num_lines) { # while we've got more lines to grab... my $block = undef; read(FILE, $block, $block_size, 0); # suck in a block seek(FILE, -2 * $block_size, 1); # back up in file by two blocks my @chunks = split /\n/, $block; # split block into lines # cat last line from this block with first line of previous block push(@lines, pop(@chunks) . shift(@lines)) if @lines; # deal with fact that current block # might have more lines than we want shift(@chunks) while(@chunks > $num_lines); # subsume this block's lines unshift(@lines, @chunks); # make note of how many lines we grabbed $num_lines -= scalar(@chunks); } close(FILE); print join("\n", @lines), "\n"; }