string.txt包含必须在第二个文件(input.csv)中搜索的字符串(此数据是唯一的),并且在匹配时必须将输出重定向到文件。
现在,我已经创建了执行此操作的代码,但是当我运行此脚本时,它会中断说“内存不足”
有人可以让我知道以最大速度并绕过“内存不足”错误的最佳方法。
我相信这是由于文件的大小以及我在此处构建的复杂哈希数据结构引起的。
string.txt的记录计数= 5611273(〜100 MB)
input.csv的记录计数= 65261242(〜2.4 GB)
以下是示例文件内容
string.txt
alpha
beta
delta
gamma
bob
tom
jerry
input.csv
alpha|a1|b2|c3
delta|a2|b2|c3
beta|a1|b2|c3
gamma|a1|b2|c3
omega|a1|b2|c3
alpha|a1|b2|c3
delta|a2|b2|c3
样本哈希数据结构
'gamma' => {
'4' => [
'a1',
'b2',
'c3'
]
},
'delta' => {
'7' => [
'a2',
'b2',
'c3'
],
'2' => [
'a2',
'b2',
'c3'
]
},
代码
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my %hash;
my $key;
local $"="|"; #"
my $count=1;
open(my $INPUT_FH,'<','/home/chidori/input.csv') or die "Can't open the file $!\n";
while(my $line = <$INPUT_FH>) {
chomp($line);
my @line = split (/\|/,$line);
my $key = shift @line;
push (@{$hash{$key}{$count}},@line);
$count++;
}
#print Dumper (\%hash);
close($INPUT_FH);
open(my $STRING_FH,'<','/home/chidori/string.txt') or die "Can't open the file $!\n";
while( my $search_string = <$STRING_FH> ) {
chomp($search_string);
if (exists $hash{$search_string} ) {
foreach my $k( keys %{$hash{$search_string}}) {
my @line_to_print;
push (@line_to_print,$search_string);
push (@line_to_print,@{$hash{$search_string}{$k}});
print "@line_to_print\n"; #Temporarily printing it to STDOUT. But need to redirect it to a outfile
}
}
}
close($STRING_FH)
Chidori,有几种可能的解决方案,其中一种试图与您已经拥有的解决方案保持紧密联系。另一个人会将整个东西视为数据库。
因此,以下是有关您的策略的一些评论:
此刻,您尝试从2.4GB文件构建巨大的数据结构,然后读取较小的数据结构,以查看是否存在匹配项。您可以采用另一种方法,将'string.txt'读入一个散列中,并使用密钥作为文件的每一行以及任何值(undef?)。
如果您确实想将输入文件用作CSV,请使用'|' 作为分隔符(use Text::CSV
如果可能)。如果是类似文件的纯ASCII,则在'|'上分割 是适当的和更快的。
由于您要打印@line_to_print,因此实际上没有必要先创建该数组,然后将东西压入它,然后打印出元素。print
提供所谓的“列表上下文”,因此print $search_string, @{$hash->{$search_string}{$k}}
就足够了,并且可以再次加快速度。
在读取文件时,Perl确实具有内置的行计数器
我希望这能给您足够的提示,让您知道如何才能在有限的内存限制下使它工作,甚至加快速度。这样就无需首先对文件进行排序,散列机制本身具有超快速的查找方法。
今天是下雨天,如果您需要更多帮助,则是进行Perl编码的好时机。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句