Как посчитать количество совпадений в группе захвата регулярных выражений - Perl - PullRequest
0 голосов
/ 05 декабря 2018

Мне нужен способ подсчета количества совпадений в группе захвата регулярных выражений с использованием Perl или Bash.Я могу сделать это в Powershell, но не на любом из этих языков.Вы, ребята, помогли мне с работой моего Regex, но каждый пример, который я вижу, просто печатает группы захвата.Печать результатов совпадений мне не помогает, мне нужно посчитать количество совпадений в каждой группе.

Вот пример данных для регулярного выражения (это вывод команды, поэтому это не статические данные и неэто из файла)

   JobID           Type State Status               Policy Schedule     Client Dest Media Svr Active PID
   41735         Backup  Done      0     Policy_name_here    daily hostname001 MediaSvr1       8100
   41734         Backup  Done      0     Policy_name_here    daily hostname002 MediaSvr1       7803
   41733         Backup  Done      0     Policy_name_here    daily hostname004 MediaSvr1       7785
   41732         Backup  Done      0     Policy_name_here    daily hostname005 MediaSvr1       27697
   41731         Backup  Done      0     Folicy_name_here    daily hostname006 MediaSvr1       27523
   41730         Backup  Done      0     Policy_name_here    daily hostname007 MediaSvr1       27834
   41729         Backup  Done      0     Policy_name_here        - hostname008 MediaSvr1       27681
   41728         Backup  Done      0     Policy_name_here        - hostname009 MediaSvr1       27496
   41727 Catalog Backup  Done      0              catalog     full hostname010 MediaSvr1       27347
   41712 Catalog Backup  Done      0              catalog        - hostname004                 30564 

Я не могу использовать именованные группы захвата, так как использую Perl 5.8.5

мое регулярное выражение

/(\d+)?\s+((\b[^\d\W]+\b)|(\b[^\d\W]+\b\s+\b[^\d\W]+\b))?\s+((Done)|(Active)|(\w+\w+\-\w\-+))?\s+(\d+)?\s+((\w+)|(\w+\_\w+)|(\w+\_\w+\_\w+))?\s+((b[^\d\W]+\b\-\b[^\d\W]+\b)|(\-)|(\b[^\d\W]+\b))?\s+((\w+\.\w+\.\w+)|(\w+))?\s+((\w+\.\w+\.\w+)|(\w+))?\s+(\d+)?/g

Каждая группа захвата соответствует столбцу, и мне нужно перетащить результаты группы захвата в переменную, чтобы я мог сосчитать, используя некоторый код where {$var -eq '0'}.count.Предполагая, что Status -eq '0' обозначает успешное резервное копирование, мне нужно подсчитать количество успешных резервных копий в группе захвата статуса.

Окончательный вывод выглядит примерно так:

Statistic.SUCCESSFUL: 20

Я сделал это уже с помощью Powershell, но Perl совершенно другой, и Bash кажется ограниченным.Если кто-нибудь знает, как выполнить вышеупомянутое на любом из этих языков, я был бы признателен за помощь.

С уважением,

DJ

1 Ответ

0 голосов
/ 05 декабря 2018
<>;  # Skip header

my $successes = 0;
while (<>) {
   chomp;
   my @row = /.../
      or do {
         die("Line $. doesn't match pattern\n");
         next;
      };

   ++$successes if $row[3] eq '0';
}

Вы также можете назвать столбцы.

<>;  # Skip header

my $successes = 0;
while (<>) {
   chomp;
   my %row;
   @row{qw( JobID Type State Status ... )}  = /.../
      or do {
         die("Line $. doesn't match pattern\n");
         next;
      };

   ++$successes if $row{Status} eq '0';
}

Наконец, если вы хотите сохранить данные в структуре данных для последующего анализа, это также возможно.

<>;  # Skip header

my @rows;
while (<>) {
   chomp;
   my %row;
   @row{qw( JobID Type State Status ... )}  = /.../
      or do {
         die("Line $. doesn't match pattern\n");
         next;
      };

   push @rows, \%row;
}

my $successes = grep { $_->{Status} eq '0' } @rows;

Наконец, этот шаблон регулярных выражений ... ужасен.Я бы пошел с чем-то вроде этого:

sub trim(_) { $_[0] =~ s/^\s++|\s++\z//rg }

my $pattern;
my @headers;
{
   my $header_line = <>;
   chomp($header_line);
   $header_line =~ s/\bDest Media Svr\b/Dest_Media_Svr/;
   $header_line =~ s/\bActive PID\b/Active_PID/;
   $pattern = join '', map { "A".length($_) } $header_line =~ /\s*\S+/g;
   @headers = map trim, unpack $pattern, $header_line;
}

my @rows;
while (<>) {
   chomp;
   my %row; @row{@headers} = map trim, unpack $pattern, $_;
   push @rows, \%row;
}

my $successes = grep { $_->{Status} eq '0' } @rows;
...