#!/usr/bin/perl -w # Simple program to delete the last line of a file. # Reads from the end of the file for effeciency # # reverse('©'), MMII, John McNamara, jmcnamara@cpan.org use strict; my $filename = shift or die "Usage: $0 file\n"; my $file_size; my $buff_size = 256; my $eol = "\n"; my $eol_size = length $eol; my $read_num = 1; my $text = ''; # Open the file in read/write mode open FILE, "+<$filename" or die "Couldn't open $filename: $!"; $file_size = -s $filename; binmode FILE; # Change the buffer size to equal the file size if the file # is smaller than the buffer. $buff_size = $file_size if $buff_size > $file_size; # Read backwards through the file until we find an eol while (($buff_size <= $file_size) and ($file_size > 0)) { # Rewind from the end of the file seek FILE, -$buff_size *$read_num, 2; # Store the current position my $current = tell FILE; # Ignore possible eol as last char on first read if ($read_num == 1) { read FILE, $text, $buff_size -$eol_size; } else { read FILE, $text, $buff_size; } # Find the last eol and truncate the file after it if ((my $offset = rindex $text, $eol) != -1) { truncate FILE, $current +$offset +$eol_size; last; } elsif ($current <= $buff_size) { # If the current file position is within the buffer # size and we haven't found an eol then there is only # one line in the file. So we truncate the whole file. truncate FILE, 0; last; } # If eol not found read backwards another time $read_num++; $file_size -= $buff_size; }