2015-01-29 3 views
0

Ниже приведен скрипт, используемый для сопоставления с образцом. Может ли кто-нибудь помочь мне в повышении эффективности этого кода. Это занимает больше времени, когда я использую большие файлы. Я не настолько осведомлен об использовании хэша. Пожалуйста, улучшите приведенный ниже код и обновите его.Perl: Match Match с использованием двух массивов и отображения

open(OUT,"> Correct.txt"); 
open(ERR,"> ERROR_Report.txt"); 
open(IN, "File1.txt"); 
my @values = <IN>; 
close IN; 
$flag=0; 
$count=0; 
open(IN, "File2.txt"); 
my @verify = <IN>; 
close IN; 

foreach my $ver(@verify){ 
    foreach my $rep(@values){ 
     if ($ver =~ /$rep/){ 
      $flag=1; 
      $count++; 
     } 
    } 

    if($flag==1){ 
     print OUT "$ver"; 
     $flag=0; 
    } 
    else{ 
     print ERR "$ver"; 
    } 
} 

print OUT "Total Count:$count"; 

Пожалуйста, помогите мне .. Спасибо заранее ..

+1

* Always * 'use strict; использовать предупреждения; '! (И немного OT; хорошее чтение: http://eev.ee/blog/2011/04/13/perl-worst-practices) – Biffen

+0

Интересно, почему массив «rep» s называется '@ values' ? – ikegami

+0

Если вы пытаетесь использовать строки, общие для обоих файлов, и строки, которые находятся в одном файле, но не в другом, попробовали ли вы использовать Unix comm (1) [http://linux.die.net/man/1/comm]? – mwp

ответ

2

Вы компиляции num_verify * шаблоны num_values ​​регулярных выражений, даже если у вас есть только num_values ​​различные узоры.

my @rep_regexps = map { qr/$_/ } @values; 

for my $ver (@verify) { 
    for my $rep_regexp (@rep_regexps) { 
     if ($ver =~ /$rep_regexp/) { 
      $flag = 1; 
      ++$count; 
     } 
    } 

    ... 
} 

Если не два из регулярных выражений вы считанные из File1.txt может соответствовать перекрытию части любым из строк, которые вы читали из File2.txt, вы можете оптимизировать выше, дополнительно.

my $reps_pattern = join '|', @values; 
my $reps_regexp = qr/$reps_pattern/; 

for my $ver (@verify) { 
    while ($ver =~ /$reps_regexp/g) { 
     $flag = 1; 
     ++$count; 
    } 

    ... 
} 

Если не два из регулярных выражений вы считанные из File1.txt может соответствовать anyof строки вы читаете из File2.txt, вы можете оптимизировать выше, дополнительно.

my $reps_pattern = join '|', @values; 
my $reps_regexp = qr/$reps_pattern/; 

for my $ver (@verify) { 
    if ($ver =~ /$reps_regexp/) { 
     $flag = 1; 
     ++$count; 
    } 

    ... 
} 
+0

Будет ли этот скрипт работать лучше, чем хеширование? – user3032425

+0

Я не вижу, как здесь можно использовать хэширование. – ikegami

+0

Я имею в виду эффективность скорости, даже если размер файла превышает 10 Мб. – user3032425

0

Было бы полезно, если бы вы могли более подробно объяснить, что вы пытаетесь выполнить. Я думаю, что это суммирует это: у вас есть файл «проверки», содержащий строки и файл «значений», содержащий шаблоны; если какой-либо заданный образец «значений» находится в «проверке», распечатайте исходную строку для вывода. Если шаблон не найден, распечатайте исходную строку до ошибки.

Что вы хотите, чтобы «общее количество» означало? Сейчас это означает, что общее количество шаблонов в «значениях» соответствует, а не общее количество строк в «проверке». Частью вашей проблемы с эффективностью является то, что вы продолжаете проверять шаблоны после того, как строка уже сопоставлена. Это по дизайну или это ошибка, которую мы можем исправить?

Действительно ли вы выполняете сопоставление с образцом или простое сравнение строк? Последний открывает несколько разных вариантов того, как мы можем это сделать. «Проверяет» файл 10 МБ или «значения»? В общем, вы должны выбрать более крупный файл как «управляющий» вход, а только читать вход без ввода в память.

use strict; 
use warnings; 

open(OUT, '>', 'Correct.txt') 
    or die "unable to open Correct.txt for writing: $!\n"; 
open(ERR, '>', 'ERROR_Report.txt') 
    or die "unable to open ERROR_Report.txt for writing: $!\n"; 

# File1.txt contains patterns for matching 
open(PATTERNS, '<', 'File1.txt') 
    or die "unable to open File1.txt for reading: $!\n"; 

# Read in patterns and remove trailing CRLF 
chomp(my @patterns = <PATTERNS>); 
my $pattern = join '|', @patterns; 
# Compute a single regex with all the patterns 
my $pattern_re = qr/$pattern/; 

close(PATTERNS); 

# File2.txt contains lines to check for patterns 
open(LINES, '<', 'File2.txt') 
    or die "unable to open File2.txt for reading: $!\n"; 

my $count = 0; 
while (my $line = <LINES>) { 
    # Remove trailing CRLF 
    chomp; 

    if ($line =~ $pattern_re) { 
    print OUT $line."\r\n"; 
    $count++; 
    } 
    else { 
    print ERR $line."\r\n"; 
    } 
} 

close(LINES); 

print OUT "Total matching lines: $count\r\n"; 
Смежные вопросы