替换数百万个正则表达式(perl)

时间:2018-09-19 08:54:45

标签: regex perl substitution

我有一个文本文件,其中包含超过一百万行文本。每行上都有一个字母数字代码,需要用名称替换。我尝试使用不同的Perl脚本来执行此操作,但是每次脚本死掉都是因为它们使用了过多的内存。我是Perl的新手,所以我想我做错了什么,这使工作变得太复杂了吗? 到目前为止,我已经尝试过:

use strict;
use warnings;

my $filename = 'names.txt';

my $data = read_file($filename);

$data =~ s/88tx0p/Author1/g;
##and then there are 1,000,000+ other substitution regexes.

write_file($filename, $data);
exit;

sub read_file {
my ($filename) = @_;

open my $in, '<:encoding(UTF-8)', $filename or die "Could not open 
'$filename' for reading $!";
local $/ = undef;
my $all = <$in>;
close $in;

return $all;
}

sub write_file {
my ($filename, $content) = @_;

open my $out, '>:encoding(UTF-8)', $filename or die "Could not open 
'$filename' for writing $!";;
print $out $content;
close $out;

return;
}

但是后来我意识到这个脚本正在尝试将输出写入原始文件,我想它会使用更多的内存?所以我尝试了以下方法:

use strict;
use utf8;
use warnings;

open(FILE, 'names.txt') || die "File not found";
my @lines = <FILE>;
close(FILE);

my @newlines;
foreach(@lines) {
$_ =~ s/88tx0p/Author1/g;
##and then there are approximately 1,000,000 other substitution regexes.
push(@newlines,$_);
}

open(FILE, '>names_edited.txt') || die "File not found";
;
print FILE @newlines;
close(FILE);

但是同样,这占用了太多的内存。请问我在使用最少的内存的情况下可以获得帮助吗?谢谢大家。

1 个答案:

答案 0 :(得分:6)

您的问题是您使用的是foreach循环。这需要您将所有行都加载到内存中,这是问题的根源。

在while循环中尝试一下:

open ( my $file, '<', 'names.txt' ) or die $!; 
open ( my $output, '>', 'names_edited.txt' ) or die $!;
select $output; #destination for print; 
while ( <$file> ) {  #reads one line at a time, sets $_
    s/88tx0p/Author1/g;   #acts on $_ by default
    print; #defaults to printing $_ to the selected filehandle $output
}

这将逐行工作(就像您的初始代码一样),但是一次只能读取一行,因此内存占用空间将大大减少。