我正在使用Perl脚本来读取CSV文件并进行一些计算.CSV文件只有两列,如下所示.
One Two
1.00 44.000
3.00 55.000
Run Code Online (Sandbox Code Playgroud)
现在这个CSV文件非常大,可以从10 MB到2GB.
目前我正在使用大小为700 MB的CSV文件.我试着在记事本中打开这个文件,excel但看起来好像没有软件打开它.
我想阅读可能是CSV文件中的最后1000行并查看值.我怎样才能做到这一点?我无法在记事本或任何其他程序中打开文件.
如果我编写一个Perl脚本,那么我需要处理完整的文件以转到文件末尾,然后读取最后1000行.
有没有更好的方法呢?我是Perl的新手,任何建议都将不胜感激.
我搜索过网络,有一些脚本可用,比如File :: Tail,但我不知道它们会在windows上运行吗?
Mic*_*man 27
该文件:: ReadBackwards模块可以读取以相反的顺序文件.只要您不依赖于顺序,这就可以轻松获得最后N行.如果你和所需的数据足够小(在你的情况下应该是这样)你可以将最后1000行读入数组然后reverse
它.
S.L*_*ott 11
在*nix中,您可以使用tail命令.
tail -1000 yourfile | perl ...
Run Code Online (Sandbox Code Playgroud)
那只会将最后1000行写入perl程序.
在Windows上,还有的GnuWin32和unxutils包都有tail
效用.
这仅与您的主要问题相关,但是当您想要检查诸如File :: Tail之类的模块是否适用于您的平台时,请检查CPAN测试人员的结果.CPAN搜索模块页面顶部的链接将引导您
查看矩阵,您会看到在所有测试的Perl版本上,此模块确实在Windows上存在问题:
没有tail,仅Perl 的解决方案并不是那么不合理。
一种方法是从文件末尾查找,然后从中读取行。如果您没有足够的线条,请从结尾处进一步寻找,然后再试一次。
sub last_x_lines {
my ($filename, $lineswanted) = @_;
my ($line, $filesize, $seekpos, $numread, @lines);
open F, $filename or die "Can't read $filename: $!\n";
$filesize = -s $filename;
$seekpos = 50 * $lineswanted;
$numread = 0;
while ($numread < $lineswanted) {
@lines = ();
$numread = 0;
seek(F, $filesize - $seekpos, 0);
<F> if $seekpos < $filesize; # Discard probably fragmentary line
while (defined($line = <F>)) {
push @lines, $line;
shift @lines if ++$numread > $lineswanted;
}
if ($numread < $lineswanted) {
# We didn't get enough lines. Double the amount of space to read from next time.
if ($seekpos >= $filesize) {
die "There aren't even $lineswanted lines in $filename - I got $numread\n";
}
$seekpos *= 2;
$seekpos = $filesize if $seekpos >= $filesize;
}
}
close F;
return @lines;
}
Run Code Online (Sandbox Code Playgroud)
PS 更好的标题应该是“在 Perl 中从大文件的末尾读取行”。
我在纯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;
}
Run Code Online (Sandbox Code Playgroud)
并运行此脚本,如:
$ get-x-lines-from-end.pl ./myhugefile.log 200
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
26988 次 |
最近记录: |