http://www.perlmonks.org?node_id=1095182

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks!
I am looking for an efficient way to grab the last 2 lines of a big text file...
Ideally, I would like to store the second-to-last line to a variable called $id and the last line to a variable called $name.
Of course I can read the file line-by-line but I was wondering if there is a faster way to do it, perhaps without the need of reading the whole file first.

Replies are listed 'Best First'.
Re: How can I grab the last 2 lines of a file?
by AppleFritter (Vicar) on Jul 26, 2014 at 22:05 UTC

    Take a look at File::ReadBackwards:

    #!/usr/bin/perl use strict; use warnings; use feature qw/say/; use File::ReadBackwards; tie *BW, 'File::ReadBackwards', '/path/to/your_file' or die "Cannot re +ad file: $!"; chomp(my $name = <BW>); chomp(my $id = <BW>); say "Name: $name"; say "ID: $id";

    Hope this helps!

Re: How can I grab the last 2 lines of a file?
by fishmonger (Chaplain) on Jul 26, 2014 at 23:09 UTC

    Normally, I'd suggest a pure Perl solution, such as the one AppleFritter suggested but in this case I'll suggest a mixed perl/shell solution that needs only 1 line of code.

    my ($id, $name) = split {$/}, `tail -2 /path/to/file`;

      Clever solution ++

      ... if you're on a *NIX system, or on a system that otherwise has the tail executable installed somewhere in its PATH.

        Hi Monks!
        I came across this post and it seems very helpful to a snippet of code i am trying to put together...Actually, I am interested in exactly the same thing as requested here, with the exception of removing these N (e.g. 2) lines from the file...It this possible?
Re: How can I grab the last 2 lines of a file?
by LanX (Saint) on Jul 26, 2014 at 22:04 UTC
    You need to seek on a file handle to jump to the end.

    Since its byte and not line based you'll need to read a sufficiently big trailing chunk into a line array and take the last two entries. (and if the chunk wasn't big enough try a bigger one )

    Search the archives, similar questions have been asked before and adjust the code to your needs.

    > Ideally, I would like to store the second-to-last line to ...

    Ideally someone would bring me now a banana split and a hot espresso to my sofa...

    Cheers Rolf

    (addicted to the Perl Programming Language and ☆☆☆☆ :)

    update

    ... or a strudel with vanilla ice cream... Hmm! :)

    update

    No espresso yet? Hence no tip! :(

    But at least a link http://www.google.com/search?q=read+last+n+lines+of+a+file+perl+site:www.perlmonks.org

      That's exactly the approach the unix tail command takes so it seems reasonable to assume there isn't a better way.

      strace tail -2 xterm.faq.html ... open("xterm.faq.html", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=257717, ...}) = 0 lseek(3, 0, SEEK_CUR) = 0 lseek(3, 0, SEEK_END) = 257717 lseek(3, 253952, SEEK_SET) = 253952 read(3, "href=\"manpage/resize.ps\">ps</a>\n"..., 3765) = 3765 ... write(1, "</body>\n", 8</body> ) = 8 write(1, "</html>\n", 8</html> ) = 8 read(3, "", 0) = 0 close(3) = 0 ...