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

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

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 = ИСПЫТАНО

0
coolent 2 Май 2019 в 17:04

3 ответа

Лучший ответ
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
user557597user557597 2 Май 2019 в 15:32

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

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
2
Sobrique 2 Май 2019 в 16:09

Вот способ:

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";
}
1
Toto 2 Май 2019 в 15:19