Perl Автоматизация Ha sh Население и имя ключа - PullRequest
2 голосов
/ 16 июня 2020

У меня несколько строк с ошибками. Я сопоставляю их с уже имеющимися у меня шаблонами. Если они такие же, я хочу, чтобы они попадали под ту же ошибку. Если они соответствуют шаблону, но имеют некоторые отличия от предыдущих строк в ha sh, я хочу дать ему то же имя ошибки, но с другим номером, добавленным к нему.

Вот пример входного файла:

there are 5 syntax issues with semicolon
there are 11 syntax issues with semicolon
the file contains 5 formatting issues
there are 1 syntax issues with semicolon
check script for formatting issues
2 syntax issues have been found
the file contains 1 formatting issues
6 syntax issues have been found
use warnings;
use strict;

my %errors;
my $file = "listoferrormessages.txt"

open my $fh,'<',$file or die "Could not open $file: $!";

while(my $line = <$fh>){

if( $line =~ /syntax/){

    if ($line =~ /there are \d syntax issues with semicolon/){
       #if line matching format exists in hash values, continue
       #if not, create a hash key called syntax_# where # increments one from the last key with the error name. 
        $errors{errorname} = $line;
}

    elsif ($line =~ /\d syntax issues have been found/){
       #same as above
       $errors(errorname} = $line;
}

elsif ($line =~ /format/){
#same as above
}

}
close $fh;

Я бы хотел, чтобы мой ha sh выглядел так:

$VAR1 = {
          'syntax_1' => 
                     'there are 5 syntax issues with semicolon',
          'syntax_2' => 
                     '2 syntax issues have been found',
          'format_1' => 
                     'the file contains 5 formatting issues',
          'format_2' => 
                     'check script for formatting issues'
        };

Любые указания по этому поводу быть супер полезным. Я хотел бы еще много чего добавить, но я очень не понимаю, как я могу это сделать. Это вообще возможно?

Ответы [ 3 ]

5 голосов
/ 17 июня 2020

Это выполняет то, что задают, с оставшимся вопросом о возможных типах ошибок.

Вспомогательная структура данных (%seen_error_type) предназначена для того, чтобы избежать поиска значений в каждой строке, чтобы проверить, есть ли эта ошибка - тип был замечен; с этим ha sh это просто поиск.

use warnings;
use strict;
use feature qw(say);

use Data::Dump qw(dd);  # to show complex data structures

my $file = shift // die "Usage: $0 file\n";  #/
open my $fh, '<', $file  or die "Can't open $file: $!";

my (%error, %seen_error_type, $cnt_syntax, $cnt_format);

LINE:
while (my $line = <$fh>) { 
    chomp $line;

    my $error_type = $line =~ s/[0-9]+/N/r;  # extract error type

    next LINE if exists $seen_error_type{$error_type};
    $seen_error_type{$error_type} = 1;

    if ($line =~ /syntax/) {
        ++$cnt_syntax;
        $error{ "syntax_$cnt_syntax" } = $line;
    }
    elsif ($line =~ /format/) {
        ++$cnt_format;
        $error{ "format_$cnt_format" } = $line;
    }   
    else { }  # specify how to handle unexpected error types
}       
    
dd \%error;

«Тип» ошибки сначала строится из строки путем замены числа на N; это просто следует за образцами OP, поскольку не дается никаких правил для классификации этих сообщений об ошибках. Если это действительно все, хорошо. Но я бы ожидал, что ожидаются более сложные критерии для типов ошибок.

Основная потребность в улучшении этого состоит в том, чтобы сформулировать правила для ожидаемых «типов ошибок» (структуры сообщений об ошибках).

Простое добавление неожиданных шаблонов в нашу бухгалтерию, sh типов ошибок не имеет смысла, если у нас нет какого-либо правила, как извлечь шаблон из строки. В противном случае каждая возможная строка текста может в конечном итоге стать ключом для себя, что противоречит цели всего упражнения по их классификации.

С данным входным файлом, как показано выше

{
  format_1 => "the file contains 5 formatting issues",
  format_2 => "check script for formatting issues",
  syntax_1 => "there are 5 syntax issues with semicolon",
  syntax_2 => "2 syntax issues have been found",
}

(Возможно, необходимо установить модуль Data :: Dump , который я использовал. Основной вариант: Data :: Dumper )

Еще одно примечание, поднятое в комментариях: я не понимаю, зачем добавлять ключ для каждой новой строки вместо добавления каждой ожидаемой строки типа ошибки в ссылку на массив для подходящего ключа (syntax, format , et c).

Если для этого нет конкретной c причины, я бы предпочел предложить что-то вроде

my (%error, %seen_error_type);

LINE:
while (my $line = <$fh>) { 
    chomp $line;

    my $error_type = $line =~ s/[0-9]+/N/r;  # extract error type

    next LINE if exists $seen_error_type{$error_type};
    $seen_error_type{$error_type} = 1;

    if ($line =~ /syntax/) {
        push @{$error{syntax}}, $line;
    }   
    elsif ($line =~ /format/) { 
        push @{$error{format}}, $line;
    }
    else { }  # specify how to handle unexpected error types
}

dd \%error;

Теперь у нас просто есть ссылка на массив для ключа syntax и еще один для ключа format.

Это печатает

{
  format => [
              "the file contains 5 formatting issues",
              "check script for formatting issues",
            ],
  syntax => [
              "there are 5 syntax issues with semicolon",
              "2 syntax issues have been found",
            ],
}
2 голосов
/ 22 июня 2020
Программа

zdim работоспособна, но если ваша ситуация была более сложной, то while l oop будет запутываться. Есть лучший узор, который вы можете использовать, чтобы вы могли продолжать добавлять узоры. Белый Медведь подошел близко, но все еще обладает дополнительными, специальными знаниями, запеченными в l oop.

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

my @matchers = (
    #  label    pattern
    [ 'syntax', qr/syntax/ ],
    [ 'format', qr/format/ ],
    );

l oop тогда становится примерно таким. Эта версия while работает для любого количества сопоставителей, которое вы хотите определить. Этот while не имеет специальных знаний о вводе или сопоставлении. Его задача - преобразовать все данные во что-то, чем вы сможете легко управлять позже, и сделать это без потери информации:

use v5.26;
my %hash;

LINE:
while (my $line = <$fh>) {
    chomp $line;

    foreach my $matcher ( @matchers ) {
        next unless $line =~ m/$matcher->[1]/;
        my( $n ) = $line =~ /(\d+)/;
        push $hash{ $matcher->[0] }{$n // 0}->@*, $line;
        next LINE; # or not, if you want to sort into multiple categories
        }
    }

Теперь у меня есть структура данных, в которой есть номер в сообщении об ошибке и список всех совпавших строк. Это не обязательно должна быть ваша окончательная структура данных, но она может помочь вам в этом. В конечном итоге требования к выходным данным изменятся, и если вы запекли слишком много решений в while, вам придется начинать заново. Вместо этого вы получите это независимо от результата, и это всего лишь вопрос преобразования этого во все, что вы хотите в конечном итоге. Я бы определенно хотел увидеть, как разные строки сортируются по категориям. Я могу быстро отследить неправильную категоризацию следующим образом:

{
  format => {
              "0" => ["check script for formatting issues"],
              "1" => ["the file contains 1 formatting issues"],
              "5" => ["the file contains 5 formatting issues"],
            },
  syntax => {
              1  => ["there are 1 syntax issues with semicolon"],
              2  => ["2 syntax issues have been found"],
              5  => [
                      "there are 5 syntax issues with semicolon",
                      "there are 5 syntax issues with commas",
                    ],
              6  => ["6 syntax issues have been found"],
              11 => ["there are 11 syntax issues with semicolon"],
            },
}

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

push $hash{ $matcher->[0] }{$n // 0}->@*, [$line, $.];

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

{
  format => {
              "0" => [["check script for formatting issues", 6]],
              "1" => [["the file contains 1 formatting issues", 8]],
              "5" => [["the file contains 5 formatting issues", 4]],
            },
  syntax => {
              1  => [["there are 1 syntax issues with semicolon", 5]],
              2  => [["2 syntax issues have been found", 7]],
              5  => [
                      ["there are 5 syntax issues with semicolon", 1],
                      ["there are 5 syntax issues with commas", 2],
                    ],
              6  => [["6 syntax issues have been found", 9]],
              11 => [["there are 11 syntax issues with semicolon", 3]],
            },
}
1 голос
/ 17 июня 2020

Глядя на входные данные, я вижу повторяющийся шаблон /\d+ (syntax|formatting) issues/, который дает нам представление о проблеме типа, на которую мы смотрим. по типу?

use strict;
use warnings;
use feature 'say';

use Data::Dumper;

my $regex = qr/\d+ (syntax|formatting) issues/;
my $issues;

while( <DATA> ) {
    chomp;
    next unless /$re/;

    my $type = $1;
    $type = 'format' if $type =~ /formatting/;

    push @{$issues->{$type}}, $_;
}

say Dumper($issues);

__DATA__
there are 5 syntax issues with semicolon
there are 11 syntax issues with semicolon
the file contains 5 formatting issues
there are 1 syntax issues with semicolon
check script for formatting issues
2 syntax issues have been found
the file contains 1 formatting issues
6 syntax issues have been found

Вывод

$VAR1 = {
          'format' => [
                        'the file contains 5 formatting issues',
                        'the file contains 1 formatting issues'
                      ],
          'syntax' => [
                        'there are 5 syntax issues with semicolon',
                        'there are 11 syntax issues with semicolon',
                        'there are 1 syntax issues with semicolon',
                        '2 syntax issues have been found',
                        '6 syntax issues have been found'
                      ]
        };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...