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

Perl从.zip/.gz文件中提取行,perl,compression,extract,Perl,Compression,Extract,我有一个非常大的压缩文件(.zip或.gz)。我想通过不解压缩那个非常大(1TB)的文件来节省时间和空间。它是一个文件,所以不需要担心目录。我基本上想模仿: open(FH,"<$file_name"); while(chomp($line = <FH>)){ ... } open(FH),我的第一个想法是-gzip可以“cat”到stdout。有时你有gzcat,但更常见的是gzip-dc 所以你可以这样做: open ( my $gunzip_stream, "

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

open(FH,"<$file_name");  

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

open(FH),我的第一个想法是-gzip可以“cat”到stdout。有时你有
gzcat
,但更常见的是
gzip-dc

所以你可以这样做:

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

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

不过,我认为它不适合逐行流媒体(这可能是压缩方法的一个限制。我不完全确定)。

我建议您查看一下该模块

你没有说太多你想做什么,但它看起来大致像下面的代码。
$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";
}

Unix有
gzip-dc
,它将解压并流式处理。我会惊讶地发现没有perl模块,但即使没有,您也可以将其作为exec管道打开。
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";
}