扫描一个大的.gz文件并将其字符串从已知单词中拆分(在文件中重复),并将所有拆分的字符串保存在一个.txt文件中



我正在尝试编写一个perl脚本,我正在尝试打开并读取一个.gz文件并将其与已知单词('.EOM'(,在该文件中重复多次,并将所有拆分保存在.txt或.tmp文件中。该.gz文件非常非常大(在某些GB中(。我已经尝试了许多不同的方法,但每次它都会在最后显示以下错误。 "恐慌:sv_setpvn在7号线38417185号线perl_gz1.pl用负线呼叫" 这里的"per_gz1.pl"是我的Perl文件名,"第101行"是我编写以下代码行的行:我的@spl=split('。EOM',$join(;

我不知道这是什么类型的错误以及如何解决它。任何人都可以帮助解决它吗?有没有另一种方法可以在不出现此错误的情况下执行相同的操作?提前谢谢。 我已经附上了我的完整代码。

我尝试了以下代码:

use strict ;
use warnings;
my $file = "/nfs/iind/disks/saptak/dsbnatrgd.scntcl.gz";
open(IN, "gzcat $file |",) or die "gunzip $file: $!";
my $join = join('',<IN>);
#print $join;
my @spl=split('.EOM',$join);
print @spl;
close IN;

use IO::Uncompress::Gunzip qw(gunzip $GunzipError) ;
my $input = "/nfs/iind/disks/cpc_disk0025/saptak/dsbnatrgd.scntcl.gz";
my $output = "NEW1.tmp";
gunzip $input => $output or die "gunzip failed: $GunzipErrorn";
my $data = join("", "NEW1.tmp");
#use File::Slurp;
#my $data = read_file("NEW1.tmp");
my @spl=split(/.EOM/,$data)
and
use IO::Uncompress::Gunzip qw(gunzip $GunzipError) ;
use IO::File ;
my $input = new IO::File "</nfs/iind/disks/cpc_disk0025/saptak/dsbnatrgd.scntcl.gz" or die "Cannot open 'file1.txt.gz': $!n" ;
my $buffer ;
gunzip $input => $buffer or die "gunzip failed: $GunzipErrorn";
print $buffer;
my @spl=split(".EOM",$buffer);
But same error is coming every time.

我希望数组 @spl 每次都会在指定的单词/字符串处保存带有拆分的文件,然后输出打印它。这样我就可以继续处理这个数组@spl但没有输出,并且错误"panic:sv_setpvn在 7 行 7 行第 perl_gz1.pl 38417185 行处用负 strlen 调用"显示在输出屏幕上。

如果是一次性工作,这可能是我的做法:

zcat dsbnatrgd.scntcl.gz | perl -ne'sub newf{$n||="0000";$n++;open($fh,">","output_$n.txt")||die}$fh||newf();/(.*).EOM(.*)/ and print {$fh} $1 and newf() and print {$fh} $2 or print {$fh} $_'

这将为您提供一个新文件output_nnnn.txt每次在某处看到.EOM时。nnnn00010002等等。.EOM也可以在一行的中间看到,然后是之前和之后。EOM 以及上一个文件中的最后一个字符串和下一个文件中的第一个字符串一起保留。

单行者解释说:

sub newf{
$n||="0000";
$n++;                               #increase the filename counter
open($fh,">","output_$n.txt")||die  #open a new output filehandler
}
$fh||newf();        # 1st input line: create $fh file handler if it dont exists
/(.*).EOM(.*)/     # if the input line have a .EOM mark, grab whats before and after
and print {$fh} $1 #...and print the before on current file
and newf()         #...and open new file
and print {$fh} $2 #...and print the after .EOM to the new file
or print {$fh} $_     #or if no .EOM on current line, just print it to the current output file

(或者你的意思是.EOM 标记在 .gz 文件中未压缩?在这种情况下,.gz文件可能无效(

您的方法不起作用的原因可能是因为输入非常大。您提到.gz文件是一些GB,然后输入可能比这大几倍。我在这里的方法不会尝试将所有内容一次保存在内存中,因此您的文件有多大并不重要。