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
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.
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
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
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.
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.