Найти и распечатать точное совпадение из файла, уведомить в печати, если совпадение не может быть найдено

Я использую следующий Perl-скрипт для поиска по нескольким файлам и распечатываю всю текстовую строку при совпадении определенного числа в этой строке:

#!/perl/bin/perl

use strict;
use warnings;

my @files = <c:/perl64/myfiles/*>;

foreach my $file (@files) {
  open my $file_h, '<', $file
   or die "Can't open $file: $!";

  while (<$file_h>) {
print "$file $_" if /\b1203\b/; 
print "$file $_" if /\b1204\b/;
print "$file $_" if /\b1207\b/;
  } }

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

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

Чтобы уточнить, мне все еще нужно сопоставлять и печатать каждый раз, когда число совпадает в каждом файле, а не только если оно совпадало один раз. также очень важен вывод строки, где он совпадает.

в конечном итоге это просто для того, чтобы показать, не совпадало ли число где-либо в каком-либо из файлов.

Источник отредактирован для удобства чтения

#!/perl/bin/perl

use strict;
use warnings;

my @files = <c:/perl64/myfiles/*>;

foreach my $file ( @files ) {

    open my $file_h, '<', $file or die "Can't open $file: $!";

    while ( <$file_h> ) {

        print "$file $_" if /\b1203\b/;
        print "$file $_" if /\b1204\b/;
        print "$file $_" if /\b1207\b/;
    }
}

1 ответ

Я хотел бы иметь возможность определить, когда нет совпадения для этого числа в любом из файлов

Поскольку вы просматриваете несколько файлов, вам нужно помнить, что вы видели определенное число один раз. Хэш для подсчета очень полезен здесь, и общий подход к такого рода проблемам.

Имеет смысл одновременно перемещать числа (или шаблоны) в массив. Таким образом, вам нужно всего лишь один раз перечислить их в коде, и весь код станет менее загроможденным.

my @numbers = (1203, 1204, 1205);
my %seen;
foreach my $file (@files) {
    # ...
    while (<$file_h>) {
        foreach my $number (@numbers) {
            if (/\b$number\b/) {
                print "$file $_"; 
                $seen{$number} = 1; # we don't care how many, just that we saw it
             }
        }
    }
}

# At this point, %seen contains a key for every number that was seen at least once.
# If a number was not seen, it will not have a key.

# output numbers that were not seen
foreach my $number (@numbers) {
    print "no match: $_\n" unless exists $seen{$number};
}

Используйте хеш для отслеживания того, видели ли вы уже совпадение:

#!/perl/bin/perl

use strict;
use warnings;

my @words = ('1203', '1204', '1207');

my @files = <c:/perl64/myfiles/*>;

foreach my $file (@files) {
  open my $file_h, '<', $file
    or die "Can't open $file: $!";

  my %nr_seen;

  while (<$file_h>) {
    foreach my $w (@words) {
      if (/\b$w\b/) {
        ++$nr_seen{$w};
        print "$file $_";
      }
    }
  }

  foreach my $w (@words) {
    if (!defined $nr_seen{$w}) {
      print "$file has no $w\n";  # or whatever you want to do
    }
  }
}
Другие вопросы по тегам