perlavi has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I have problems in unless condition because of which I am not getting the desired output. This is as per my analysis but my code may have some other issues also which can be surely pointed out here to get the desired output. I am getting the output as below.
Memory

Network Port

Physical Cpu

Virtual Disk

Group Cpu
My desired output is as below.
Memory

Physical Cpu
Can somebody let me know what am I missing? Also, as this is my first post here, please bare with my style of putting up question.

foreach my $line (@::FileLines) { unless(grep(/$pattern/,$line)){ my @karatSplit = split('\^', $line); print "$karatSplit[1]\n"; } }
@::FileLines contains lines from a txt file as below.
Memory^Memory^Free MBytes,80124,85490,81912.39,100,Alert,Migrate high memory consuming VM to another host.^M

DvsPortset-0:130066:Win2k3_test (e4ba25c7-5628-45d8-97a7-83331e7ad7e1)^Network Port^% Outbound Packets Dropped,0.00,0.00,0,0,OK,

DvsPortset-0:130066:Win2k3_test (e4ba25c7-5628-45d8-97a7-83331e7ad7e1)^Network Port^% Received Packets Dropped,0.00,0.00,0,0,OK,

_Total)^Physical Cpu^% Processor Time,0.63,13.49,6.27,0,OK,

Win2k3_test (e4ba25c7-5628-45d8-97a7-83331e7ad7e1)^Virtual Disk^Commands/sec,0.00,6.72,2,0,OK,

iserver6 (b93b57e2-ab74-441a-98a7-35dc71feca12)^Virtual Disk^Writes/sec,0.00,21.26,1.63,0,OK,

iserver7 (035e60d4-3073-4fcc-a78e-6a718b3b502f)^Virtual Disk^Commands/sec,0.00,104.15,18.96,0.49,OK,

Win2k8_Trace_db^Group Cpu^% Used,0.55,8.88,4.07,0,OK,
$pattern is like below
$pattern = Win2k8_Trace_db|Win2k3_test (e4ba25c7-5628-45d8-97a7-83331e7ad7e1)|iserver7 (035e60d4-3073-4fcc-a78e-6a718b3b502f)|iserver6 (b93b57e2-ab74-441a-98a7-35dc71feca12)

Replies are listed 'Best First'.
Re: unless condition not working
by Anonymous Monk on Dec 04, 2011 at 17:45 UTC
    See quotemeta, Regex::PreSuf, and read How do I post a question effectively?
    my $line = 'fee fi fo fum'; my $pat = qr/i smell the blood/; unless( grep /$pat/, $line ){ print "of an englishman\n"; } __END__

    Prints "of an englishman", because $line doesn't match $pat

    That condition is more commonly written as one of these

    unless( $line =~ /$pat/ ) { ... if( not $line =~ /$pat/ ) { ... if( $line !~ /$pat/ ) { ...

      Thanks for the reply. I used your recommendation to use qr but unfortunately it still has issues concerning to quotemeta related lines. My txt file is a combination of normal as well as quotemeta related lines. So at a time I am able to get output either for normal lines or quotemeta lines. Please correct me if I doing something wrong.

      unless($line =~ qr/$pattern/){ ... #works only for normal lines unless($line =~ qr/\Q$pattern\E/){... #both normal as well as quotemet +a related lines are failing and everything is getting list in output.

      Could you please let me know what is wrong step I am doing?

        Could you please let me know what is wrong step I am doing?

        You're using the qr operator as if it were the m operator (match), but they're not the same. See Regexp Quote-Like Operators in perlop

        And you only quotemeta arbitrary text you wish to match verbatim, not regex patterns.

        You can build an efficient regex pattern out of a list of arbitrary text with Regex::PreSuf.

Re: unless condition not working
by Anonymous Monk on Dec 05, 2011 at 08:18 UTC

    These are just stylistic issues and won't help you solve your problem, but...

    foreach my $line (@::FileLines) { unless(grep(/$pattern/,$line)){ my @karatSplit = split('\^', $line); print "$karatSplit[1]\n"; } }

    That code can be better written as:

    foreach my $line (@::FileLines) { next unless grep(...); my @karatSplit = ... }

    Also, @::FileLines looks like bad design (why are you directly accessing an array in your main module, instead of using a reference to it?)

    please bare with

    I'd rather bear with.

Re: unless condition not working
by TJPride (Pilgrim) on Dec 05, 2011 at 14:23 UTC
    One of the main problems is your regex. You need it to be intepreted as a pattern, since you have multiple items separated by |, yet you can't have the () interpreted because those are regex special characters. So you have to backslash the ().

    use strict; use warnings; my $pattern = 'Win2k8_Trace_db|Win2k3_test \(e4ba25c7-5628-45d8-97a7-8 +3331e7ad7e1\)|iserver7 \(035e60d4-3073-4fcc-a78e-6a718b3b502f\)|iserv +er6 \(b93b57e2-ab74-441a-98a7-35dc71feca12\)'; @::FileLines = <DATA>; for (@::FileLines) { chomp; next if !$_ || m/$pattern/; @_ = split /\^/; print "$_[1]\n"; } __DATA__ Memory^Memory^Free MBytes,80124,85490,81912.39,100,Alert,Migrate high +memory consuming VM to another host.^M DvsPortset-0:130066:Win2k3_test (e4ba25c7-5628-45d8-97a7-83331e7ad7e1) +^Network Port^% Outbound Packets Dropped,0.00,0.00,0,0,OK, DvsPortset-0:130066:Win2k3_test (e4ba25c7-5628-45d8-97a7-83331e7ad7e1) +^Network Port^% Received Packets Dropped,0.00,0.00,0,0,OK, _Total)^Physical Cpu^% Processor Time,0.63,13.49,6.27,0,OK, Win2k3_test (e4ba25c7-5628-45d8-97a7-83331e7ad7e1)^Virtual Disk^Comman +ds/sec,0.00,6.72,2,0,OK, iserver6 (b93b57e2-ab74-441a-98a7-35dc71feca12)^Virtual Disk^Writes/se +c,0.00,21.26,1.63,0,OK, iserver7 (035e60d4-3073-4fcc-a78e-6a718b3b502f)^Virtual Disk^Commands/ +sec,0.00,104.15,18.96,0.49,OK, Win2k8_Trace_db^Group Cpu^% Used,0.55,8.88,4.07,0,OK,

      Thanks TJPride.. Infact () inside the pattern was the issue. Your suggestion worked absolutely fine. Thanks again..