100万行を超えるテキストを含むテキストファイルがあります。各行には、名前で置き換える必要のある英数字コードがあります。さまざまな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);
しかし、繰り返しになりますが、これはメモリを使いすぎました。最小限のメモリを使用しながらこれを行う方法についてサポートをいただけますか?皆さん、ありがとうございました。
あなたの問題はあなたが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
}
これは(最初のコードのように)行ごとに機能しますが、一度に1行しか読み取らないため、メモリフットプリントは大幅に少なくなります。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加