Поиск вхождений содержимого файла в другом файле - PullRequest
0 голосов
/ 08 сентября 2010

Я хочу найти содержимое файлов в каталоге на наличие слов в файлах в другом каталоге. Есть ли лучший способ сделать это, чем следующий? (Лучше разумно использовать память)

Более конкретно:

папка 1 имеет несколько файлов, каждый файл имеет несколько строк текста. папка 2 имеет несколько файлов, каждый файл имеет несколько слов, каждое в своей строке. Что я хочу сделать, это подсчитать количество вхождений каждого слова в каждом файле в папке 2 в каждой строке каждого файла папки 1. Надеюсь, это не слишком запутало.

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
        }
    } 
}

1 Ответ

1 голос
/ 08 сентября 2010

Одно очевидное улучшение заключается в том, чтобы сначала открывать все файлы категорий в отдельном цикле и кэшировать слова в них в хэш массивов (ключ хеша - это имя файла) или в один большой массив, если вам все равно, какой поиск слово пришло из какого файла.

Это избавит вас от необходимости перечитывать файлы поиска для каждой строки в каждом $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
}

Кроме того, если это настоящие "слова", то есть категория "кошка" должна соответствовать "кошачьей собаке", а не "кошке", я бы посчитал использование слова, разделив вместо регулярного выражения:

foreach my $line (<$fileh>) {
    my @words = split(/\s+/, $line);
    foreach my $word (@words) {
        $categories{$word}++ if exists $categories{$word};
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...