Go to content Go to navigation Go to search

Perl: Reading the last line · Nov 20, 12:21 PM by Dylan Doxey

So, you want to read the last line of a file which could potentially be really big?

Well, the easy thing is to just read all the lines until you get to the last one. The hard way is to read the file from the last character forward, skipping any trailing newlines until you get to the first newline which is not trailing.

Maybe this is better expressed in code.

sub _get_last_line {
    my ( $filename ) = @_;

    # Return emtpy string if the log doesn't exist
    return q{} if ( ! -e $filename );

    # Return empty string if the file is empty
    my $cursor = ( stat( $filename ) )[7];
    return q{} if ( $cursor == 0 );

    # Otherwise open the file and read the last line
    my $prior_umask = umask 0000;
    my $open_ok = open my $log_fh, '<', $filename
    umask $prior_umask;

    my $last_line = q{};

    if ( !$open_ok ) {
        
        warn "open '$filename': $OS_ERROR";
    }
    else {

        my $skipping_trailing_nl = 1;
        my $character = q{};
        my $seeking = 1;

        binmode $log_fh;
        
        while( $character ne "\n" && $seeking ) {
            
            $last_line = $character . $last_line;
            
            $seeking = sysseek $log_fh, $cursor,    0;
            sysread $log_fh, $character, 1;
            $cursor--;
            
            if ( $skipping_trailing_nl ) {
            
                if ( $character eq "\n" ) {
                    $character = q{};
                }   
                elsif ( $character ) {
                    $skipping_trailing_nl = 0;
                }   
            }   
        }   
        close $log_fh;
    }   
    return $last_line;
}   

Commenting is closed for this article.