2011-07-12 38 views
2

如何获取存储在变量中的文件的最后几行?在linux上,如果它在一个文件中,我会使用tail命令。获取存储在变量中的文件的最后几行

1) How can I do this in perl if the data is in a file? 
2) How can I do this if the content of the file is in a variable? 

回答

3

在某种程度上,这取决于文件的大小以及您想要的行数。如果它会很大,你需要小心,因为将它们全部读入内存需要比读取文件的最后部分更长的时间。

如果它很小。最简单的方法可能是将File::Slurp存入内存中,split由记录分隔符组成,并保留最后n条记录。实际上,如下所示:

# first line if not yet in a string 
my $string = File::Slurp::read_file($filename); 
my @lines = split(/\n/, $string); 
print join("\n", @lines[-10..-1]) 

如果它太大而不能找到内存,则最好直接使用文件系统操作。当我这样做时,我打开文件并使用seek()并读取文件的最后4k左右,并向后重复,直到有足够的数据才能获取我需要的记录数。

不是一个详细的答案,但问题可能是一个更具体的触摸。

5

读取文件尾部附近的seek并开始读取。例如,

open my $fh, '<', $file; 
seek $fh, -1000, 2; 
my @lines = <$fh>; 
close $fh; 

print "Last 5 lines of $file are: ", @lines[-5 .. -1]; 

根据什么是文件或你想要多少线看,你可能需要使用不同的幻数比上面-1000

你可以做一个变量类似的东西,无论是

open my $fh, '<', \$the_variable; 
seek $fh, -1000, 2; 

或只是

open my $fh, '<', \substr($the_variable, -1000); 

会给你产生在$the_variable过去的1000个字符的I/O处理。

4

CPAN上的File::ReadBackwards模块可能是您想要的。你可以这样使用它。非常

use File::ReadBackwards 
my $bw = File::ReadBackwards->new("some_file"); 
print reverse map { $bw->readline() } (1 .. 3); 

在内部,它寻求()s到接近文件的末尾,并查找行尾,所以它应该是与内存相当有效,甚至是:这将打印的最后三个文件中的行大文件。

0

我知道这是一个古老的问题,但我找到了它,同时寻找一种方式来搜索文件的第一个和最后一个k行模式。

对于尾部部分,除了seek(如果文件是可搜索的),它会节省一些内存以使用旋转缓冲区,如下所示(返回最后k行,如果少于$k则返回更少值):

my $i = 0; my @a; 
while (<$fh>) { 
    $a[$i++ % $k] = $_; 
} 
my @tail = splice @a,0,$i % $k; 
splice @a,@a,0,@tail; 
return @a; 
相关问题