Perl从.zip / .gz文件中提取行

时间:2015-02-19 22:39:00

标签: perl compression extract

我有一个非常大的压缩文件(.zip或.gz)。我想通过不解压缩那个非常大的(1TB)文件来节省时间和空间。它是一个单独的文件,因此无需担心目录。我基本上想模仿:

open(FH,"<$file_name");  

while(chomp($line = <FH>)){  ... } 

这可能吗?如果有,怎么样? 非常感谢 麦克

2 个答案:

答案 0 :(得分:2)

我的第一个想法是 - gzip can&#39; cat&#39;到stdout。有时您有gzcat但更常见gzip -dc <filename>

所以你可以这样做:

open ( my $gunzip_stream, "-|", "gzip -dc $gzip_file" or die $!;
while ( <$gunzip_stream> ) {
     print;
}

快速谷歌建议IO::Compress::Gunzip也可以做到这一点。

  

如果您运行Perl 5.005或更高版本,则从IO :: Uncompress :: Gunzip返回的对象$ z可以像IO :: File文件句柄一样使用。这意味着所有正常的输入文件操作都可以使用$ z执行。例如,要从压缩文件/缓冲区中读取一行,您可以使用这些表单中的任何一种

use IO::Uncompress::Gunzip;
my $z = new IO::Uncompress::Gunzip $input [OPTS]
        or die "IO::Uncompress::Gunzip failed: $GunzipError\n";

其中一个:

$line = $z->getline();
$line = <$z>;

对于zip文件来说,它有点困难。您可以使用Archive::Zip,但zip文件可以包含多个成员。即便如此:

# Read a Zip file
my $somezip = Archive::Zip->new();
unless ( $somezip->read( 'someZip.zip' ) == AZ_OK ) {
    die 'read error';
}

foreach my $member ( $somezip -> members() ) { 
   print $member -> content();
}

我不会认为它也适用于逐行流媒体。 (这可能是压缩方法的限制。我并不完全确定)。

答案 1 :(得分:1)

我建议您查看Archive::Zip::MemberRead模块。

你对自己想做的事情并不多说,但看起来大致如下代码。 $zip_fh不是一个真正的文件句柄 - 只是一个方法,使其看起来像一个 - 所以你不能使用<$zip_fh>从中读取。

此外,getline返回每一行,并且从末尾剥离了行终止符,因此不需要chomp。如果您正在阅读已经在不同标准行结束的平台上编写的文件,那么您可能不得不搞砸诸如

之类的内容。
Archive::Zip::MemberRead->setLineEnd("\r\n")

但通常你可以忘掉它。

use strict;
use warnings;

use Archive::Zip;
use Archive::Zip::MemberRead;

my $zip_file = 'myfile.zip';

my $zip    = Archive::Zip->new($zip_file) or die $!;
my $member = $zip->memberNamed('path/to/item.txt');
my $zip_fh = $member->readFileHandle;

while ( defined( my $line = $zip_fh->getline ) ) {
  print $line, "\n";
}
相关问题