Recipe 8.10 Removing the Last Line of a File

8.10.1 Problem

You'd like to remove the last line from a file.

8.10.2 Solution

Use the standard (as of v5.8) Tie::File module and delete the last element from the tied array:

use Tie::File;

tie @lines, Tie::File, $file        or die "can't update $file: $!";
delete $lines[-1];

8.10.3 Discussion

The Tie::File solution is the most efficient solution, at least for large files, because it doesn't have to read through the entire file to find the last line and doesn't read the entire file into memory. It is, however, considerably slower for small files than code you could implement yourself by hand. That doesn't mean you shouldn't use Tie::File; it just means you've optimized for programmer time instead of for computer time.

If you don't have Tie::File and can't install it from CPAN, read the file a line at a time and keep track of the byte address of the last line you've seen. When you've exhausted the file, truncate to the last address you saved:

open (FH, "+<", $file)              or die "can't update $file: $!";
while (<FH>) {
    $addr = tell(FH) unless eof(FH);
truncate(FH, $addr)                 or die "can't truncate $file: $!";

Remembering the offset is more efficient than reading the whole file into memory because it holds only one given line at a time. Although you still have to grope your way through the whole file, you can use this technique on files larger than available memory.

8.10.4 See Also

The documentation for the standard Tie::File module; the truncate and tell functions in perlfunc(1) and in Chapter 29 of Programming Perl; your system's open(2) and fopen(3) manpages; Recipe 8.18