我需要将包含2200万行的大文件(2GB)与另一个文件进行比较。在使用Tie :: File时我花了更多的时间来处理它。所以我已经通过'while'完成了它,但问题仍然存在。看下面的代码......
use strict;
use Tie::File;
# use warnings;
my @arr;
# tie @arr, 'Tie::File', 'title_Nov19.txt';
# open(IT,"<title_Nov19.txt");
# my @arr=<IT>;
# close(IT);
open(RE,">>res.txt");
open(IN,"<input.txt");
while(my $data=<IN>){
chomp($data);
print"$data\n";
my $occ=0;
open(IT,"<title_Nov19.txt");
while(my $line2=<IT>){
my $line=$line2;
chomp($line);
if($line=~m/\b$data\b/is){
$occ++;
}
}
print RE"$data\t$occ\n";
}
close(IT);
close(IN);
close(RE);
所以帮我减少它......
答案 0 :(得分:2)
这有很多不妥之处。
除了通常的(缺少use strict
,use warnings
,使用2参数open()
,不检查open()
结果,使用全局文件句柄),具体在您的情况下,问题是您为第一个文件的每一行打开/读取/关闭第二个文件。这将非常缓慢。
我建议您打开文件title_Nov19.txt
一次,将所有行读入数组或哈希或其他内容,然后关闭它;然后你可以打开第一个文件input.txt
并沿着那个文件进行比较,与数组中的内容进行比较,这样你就不必一直重新打开第二个文件。
我建议你阅读一些关于风格/等的基本文章。因为如果你的问题实际上是用模糊的现代标准写的,你的问题可能会得到更多关注。
答案 1 :(得分:0)
我尝试构建一个具有更好结构的小示例脚本,但我不得不说,男人,你的问题描述真的很不清楚。每次@LeoNerd在答案中解释时,不读取整个比较文件非常重要。然后我使用哈希来跟踪匹配计数:
#!/usr/bin/env perl
use strict;
use warnings;
# cache all lines of the comparison file
open my $comp_file, '<', 'input.txt' or die "input.txt: $!\n";
chomp (my @comparison = <$comp_file>);
close $comp_file;
# prepare comparison
open my $input, '<', 'title_Nov19.txt' or die "title_Nov19.txt: $!\n";
my %count = ();
# compare each line
while (my $title = <$input>) {
chomp $title;
# iterate comparison strings
foreach my $comp (@comparison) {
$count{$comp}++ if $title =~ /\b$comp\b/i;
}
}
# done
close $input;
# output (sorted by count)
open my $output, '>>', 'res.txt' or die "res.txt: $!\n";
foreach my $comp (@comparison) {
print $output "$comp\t$count{$comp}\n";
}
close $output;
只是为了让你开始...如果有人想进一步研究这些:这些是我的测试文件:
<强> title_Nov19.txt 强>
This is the foo title
Wow, we have bar too
Nothing special here but foo
OMG, the last title! And Foo again!
<强> input.txt中强>
foo
bar
该程序的结果写入 res.txt :
foo 3
bar 1
答案 2 :(得分:0)
这是使用memowe(谢谢)数据的另一个选项:
use strict;
use warnings;
use File::Slurp qw/read_file write_file/;
my %count;
my $regex = join '|', map { chomp; $_ = "\Q$_\E" } read_file 'input.txt';
for ( read_file 'title_Nov19.txt' ) {
my %seen;
!$seen{ lc $1 }++ and $count{ lc $1 }++ while /\b($regex)\b/ig;
}
write_file 'res.txt', map "$_\t$count{$_}\n",
sort { $count{$b} <=> $count{$a} } keys %count;
按数字排序的输出到res.txt
:
foo 3
bar 1
构建并使用引用元字符(\Q$_\E
)的交替正则表达式,因此只需要对大文件的行进行一次传递。哈希%seen
用于确保输入的单词每行只计算一次。
希望这有帮助!
答案 3 :(得分:0)
试试这个:
grep -i -c -w -f input.txt title_Nov19.txt&gt; res.txt