我想在目录中搜索文件的内容,以查找另一个目录中文件中的文字。有没有比以下更好的方法呢? (通过更好的平均内存使用)
更具体地说:
文件夹1有几个文件,每个文件有几行文字。 文件夹2有几个文件,每个文件有几个单词,每个单词都在其行上。 我想要做的是计算文件夹1的每个文件的每行中文件夹2中的每个文件中每个单词的出现次数。 我希望这不会太混乱。
open my $output, ">>D:/output.txt";
my @files = <"folder1/*">;
my @categories = <"folder2/*">;
foreach my $file (@files){
open my $fileh, $file || die "Can't open file $companyName";
foreach my $line (<$fileh>){
foreach my $categoryName (@categories){
open my $categoryFile, $categoryName || die "Can't open file $categoryName";
foreach my $word(<$categoryFile>){
#search using regex
}
#print to output
}
}
}
答案 0 :(得分:1)
一个显而易见的改进是首先在一个单独的循环中打开所有类别文件,并将其中的单词缓存到数组的散列(散列键是文件名),或者只是一个大数组,如果你不关心哪个搜索单词来自哪个文件。
这样可以避免为每个$file
中的每一行重新读取搜索文件 - 并帮助摆脱讨价还价中的重复搜索词。
use File::Slurp;
open my $output, ">>D:/output.txt";
my %categories = ();
my @files = <"folder1/*">;
my @categories = <"folder2/*">;
foreach my $categoryName (@categories) {
my @lines = read_file($categoryName);
foreach my $category (@lines) {
chomp($category);
$categories{$category} = 0;
}
}
# add in some code to uniquify @categories
foreach my $file (@files) {
open my $fileh, $file || die "Can't open file $companyName";
foreach my $line (<$fileh>) {
foreach my $category (@categories) {
# count
}
}
# output
}
另外,如果这些是真正的“单词” - 意味着“猫”的类别需要匹配“猫狗”但不匹配“mcat” - 我会通过分裂而不是正则表达式计算单词用法:
foreach my $line (<$fileh>) {
my @words = split(/\s+/, $line);
foreach my $word (@words) {
$categories{$word}++ if exists $categories{$word};
}
}