Perl向后读取和gzip文件

Perl向后读取和gzip文件,perl,gzip,Perl,Gzip,我想从gzip文件中逐行向后读取。我知道ReadBackwards模块,但是如何让它在gzip文件上工作呢?我应该使用另一个模块吗?您需要首先解压缩文件。您不能(轻松地)随机查找gzip文件。为什么要反向读取?尝试向后读取压缩文件不会提高性能。您必须首先解压缩它(要理解字节n的含义,您必须首先解压缩字节0..n) 在速度方面,您可能不会比以下各项更好: #!/usr/bin/perl use strict; use warnings; die "usage: $0 filename" unl

我想从gzip文件中逐行向后读取。我知道ReadBackwards模块,但是如何让它在gzip文件上工作呢?我应该使用另一个模块吗?

您需要首先解压缩文件。您不能(轻松地)随机查找gzip文件。

为什么要反向读取?尝试向后读取压缩文件不会提高性能。您必须首先解压缩它(要理解字节n的含义,您必须首先解压缩字节0..n)

在速度方面,您可能不会比以下各项更好:

#!/usr/bin/perl

use strict;
use warnings;

die "usage: $0 filename" unless defined(my $file = shift);

open my $fh, "<:gzip", $file
    or die "could not open $file: $!";

my @lines;
while (<$fh>) {
    push @lines, $_;
    shift @lines if @lines > 10;
}

print @lines;
#/usr/bin/perl
严格使用;
使用警告;
除非定义(my$file=shift),否则为“用法:$0文件名”;

打开我的$fh,“不要将文件存储在内存中。将其存储在SQLite或类似的数据库中,并在读取和插入数据库时使用行号的顺序索引字段

当文件完全存储在数据库中时,通过使用降序排序对索引进行排序,向后遍历行。您可以根据需要快速跳转数据库,还可以使用数据库查询来查找行。速度不会像有大量RAM或固态驱动器时那样快,但这将是一个非常大的问题而不是像你所说的那样处理压缩文件


计算机编程就是要在有限的范围内找到创造性的解决方案。你受到RAM的限制,以及你处理压缩文件的事实。你必须解压文件才能向后浏览,但你无法将其放入RAM。因此,你必须将数据放在某个地方,而这就几乎离开了磁盘向后浏览数据库比浏览平面文件更容易,因此请使用数据库了解它的用途,然后继续。

我没有一个很好的方法来测试它,但我认为从

open my $handle, '-|', '/usr/bin/gzcat', $filename;
这将允许您逐行遍历文件,如中所示

foreach my $line (<$handle>) {
  do stuff with $line ...
}
foreach my$行(){
用$line做一些事情。。。
}
我的理解是,这不会使整个文件变得含糊不清,应该有助于提高大文件的内存。如果我错了,希望有人会来用鱼扇我耳光

我也知道这是向前发展的,但我希望你现在不需要从内存的角度倒退。如果你仍然这样做,也许你可以做一些修改,将其与File::backwards一起使用


现在,我的(Ubuntu)上似乎没有
gzcat
系统,虽然我发现很多参考资料都说
gzcat
zcat
gunzip-c
gzip-dc
等程序名YMMV相同。我还是希望这个方法是合理的。

我的情况是,相关文件相当大,精确地说是几gb,我不知道有多少个lines我需要提前从底层处理。@pythonic然后就没有办法做你想做的事情了,这不是非常非常慢。gzip带有周期性的流重置是可以勉强找到的(不是从PerlIO内部,但你可以编写代码来利用它)没有周期性流重置的.gzip是100%不可查找的,这可能就是您所拥有的。我不在乎搜索到底是否很慢。我想要避免的是必须将整个文件存储在内存中。我不知道在处理完它们之前需要多少行。我尤其不能保证不需要读取整个文件文件。@pythonic隐喻您需要将其解压缩到一个文件中,然后使用
file::Backwards
来阅读它。到目前为止,答案已经解释了为什么您不能做自己想做的事情。可能还有其他选项;您能提供更多关于您实际目标的详细信息吗?文件中有哪些内容,为什么您无法说出您需要做多少直到你看到它为止?例如,两次通过的方法行吗?@Poculus-两次通过的方法行。但是,我最终采用了chas的方法。我的问题是我有非常大的日志文件,其中包含与几个不同主题相关的消息。对于每个主题,我需要在w上的最后一行之前抓取该行有些条件(复杂的正则表达式)是正确的。这通常意味着我需要读取不超过文件结尾的1-2%,但偶尔,我从底部读取10-20%,在最坏的情况下,我必须读取文件的50%。