How can I read lines from the end of file in Perl?

后端 未结 11 1906
夕颜
夕颜 2020-12-06 02:41

I am working on a Perl script to read CSV file and do some calculations. CSV file has only two columns, something like below.

One Two
1.00 44.000
3.00 55.000         


        
相关标签:
11条回答
  • 2020-12-06 03:17

    Without relying on tail, which I probably would do, if you have more than $FILESIZE [2GB?] of memory then I'd just be lazy and do:

    my @lines = <>;
    my @lastKlines = @lines[-1000,-1];
    

    Though the other answers involving tail or seek() are pretty much the way to go on this.

    0 讨论(0)
  • 2020-12-06 03:23

    I've wrote quick backward file search using the following code on pure Perl:

    #!/usr/bin/perl 
    use warnings;
    use strict;
    my ($file, $num_of_lines) = @ARGV;
    
    my $count = 0;
    my $filesize = -s $file; # filesize used to control reaching the start of file while reading it backward
    my $offset = -2; # skip two last characters: \n and ^Z in the end of file
    
    open F, $file or die "Can't read $file: $!\n";
    
    while (abs($offset) < $filesize) {
        my $line = "";
        # we need to check the start of the file for seek in mode "2" 
        # as it continues to output data in revers order even when out of file range reached
        while (abs($offset) < $filesize) {
            seek F, $offset, 2;     # because of negative $offset & "2" - it will seek backward
            $offset -= 1;           # move back the counter
            my $char = getc F;
            last if $char eq "\n"; # catch the whole line if reached
            $line = $char . $line; # otherwise we have next character for current line
        }
    
        # got the next line!
        print $line, "\n";
    
        # exit the loop if we are done
        $count++;
        last if $count > $num_of_lines;
    }
    

    and run this script like:

    $ get-x-lines-from-end.pl ./myhugefile.log 200
    
    0 讨论(0)
  • 2020-12-06 03:24
    perl -n -e "shift @d if (@d >= 1000); push(@d, $_); END { print @d }" < bigfile.csv
    

    Although really, the fact that UNIX systems can simply tail -n 1000 should convince you to simply install cygwin or colinux

    0 讨论(0)
  • 2020-12-06 03:26

    You could use Tie::File module I believe. It looks like this loads the lines into an array, then you could get the size of the array and process arrayS-ze-1000 up to arraySize-1.

    Tie::File

    Another Option would be to count the number of lines in the file, then loop through the file once, and start reading in values at numberofLines-1000

    $count = `wc -l < $file`;
    die "wc failed: $?" if $?;
    chomp($count);
    

    That would give you number of lines (on most systems.

    0 讨论(0)
  • 2020-12-06 03:28

    You should absolutely use File::Tail, or better yet another module. It's not a script, it's a module (programming library). It likely works on Windows. As somebody said, you can check this on CPAN Testers, or often just by reading the module documentation or just trying it.

    You selected usage of the tail utility as your preferred answer, but that's likely to be more of a headache on Windows than File::Tail.

    0 讨论(0)
提交回复
热议问题