Perl grep несколько шаблонов - PullRequest
0 голосов
/ 02 мая 2019

Я пытаюсь выполнить поиск и сопоставить два шаблона

if(grep /mystatus eq 'PASSED\||FAILED/ && /myupdate ne TEST/, @try), тогда должно появиться "ok".Однако это не соответствует правильно.он печатает «не совпадает».Не могли бы вы предложить?Заранее спасибо.

use strict;
use warnings;
open(FILE,"myfile");
my @file = <FILE>;


if(grep /mystatus eq 'PASSED\||FAILED/ && /myupdate ne TEST/, @file)
{
print "ok";
}
else
{
print "not matching\n";
}

myfile содержит следующие строки

mystatus = PASSED

myupdate = TESTED

Ответы [ 3 ]

2 голосов
/ 02 мая 2019

ОК, так что на самом деле никто не написал о реальной проблеме с вашим кодом.

grep соответствует условию. Вы указываете //, что означает «соответствовать регулярному выражению», и тогда вы не предоставляете фактическое регулярное выражение.

Также вы избегаете своего |, который является условным, поэтому вы соответствуете литералу.

print "This matches\n" if "myupdate ne TEST" =~ /myupdate ne TEST/;

Это не будет делать то, что вы хотите.

Если вы хотите выполнить regex тест, вам нужно что-то немного другое, например:

Так, например:

while ( <DATA> ) {
   print "Matching line $_" if m/mystatus=(PASSED|FAILED)/;
}

__DATA__
mystatus=PASSED
myupdate=TESTED

Вторая проблема - вы читаете свой файл в @try, который разбивается на основе строк. Таким образом, оба шаблона никогда не будут совпадать , поскольку они оцениваются отдельно.

Вы можете использовать несколько подходов к этому, но один из них - установить "$ /", который является разделителем записей, - установить undef, и все будет считано в один элемент массива, но ... тогда он получит немного банально, если вы потом хлебаете в массив.

Так что я бы настоятельно рекомендовал вам не использовать grep для этой задачи, во-первых - grep отлично подходит для фильтрации списка элементов по условию, но на самом деле это не то, что вы пытаетесь сделать ,

Так что я бы посоветовал вам вообще не делать grep, а вместо этого:

#!/usr/bin/env perl; 
use strict;
use warnings;
use Data::Dumper; 

my %values = map { /(\w+)=(\w+)/ } <DATA>;


#for debug
print Dumper \%values;

print "OK\n" if $values{'mystatus'} eq 'PASSED' and $values{'myupdate'} eq 'TESTED'; 

__DATA__
mystatus=PASSED
myupdate=TESTED

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

Или использовать более сложную логику:

#!/usr/bin/env perl; 
use strict;
use warnings;
use Data::Dumper; 

my %values = map { /(\w+)=(\w+)/ } <DATA>;


#for debug
print Dumper \%values;

print "OK\n" if ( $values{'mystatus'} eq 'PASSED' or $values{'mystatus'} eq 'FAILED' ) 
                   and $values{'myupdate'} eq 'TESTED'; 

__DATA__
mystatus=PASSED
myupdate=TESTED
1 голос
/ 02 мая 2019
use strict;
use warnings;

$/ = undef;


my $str = <DATA>;

if ( $str =~ /(?s)^(?=.*mystatus\s*=\s*(?:PASSED|FAILED))(?=.*myupdate\s*=\s*(?!TEST\b))/ ) {
    print "ok";
}
else {
    print "not matching\n";
}


__DATA__

mystatus=PASSED

myupdate=TESTED
1 голос
/ 02 мая 2019

Вот путь:

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

my $file;
{ 
    local $/ = undef;
    open my $fh, '<', 'path/to/file' or die "unable to open file: $!"
    $file = <$fh>;
}
if($file =~  /^(?=.*\bmystatus=(?:PASSED|FAILED)\b)(?=.*\bmyupdate=TESTED\b)/) {
    say "ok";
} else {
    say "not matching";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...