0

I have an array @astreams which contains following values

jatm5_INT jatm5_APPL jatm5_JAVA jatm5_RLS jatm5_EDAG jatm5_REC 

I want to search a string in it with following construct

if ( @astreams !~ /$stream_s/ )

and want to print something in case of match or not but it did not work

I am using CCPERL (ClearCase Perl): This is perl, v5.8.6 built for MSWin32-x86-multi-thread

6
  • btw. I am using CCPERL (ClearCase Perl): This is perl, v5.8.6 built for MSWin32-x86-multi-thread Commented Jan 6, 2017 at 8:28
  • 4
    can you be more specific? what did you tried? what is "it did not work" Commented Jan 6, 2017 at 8:31
  • Shame, your Perl is too old for the smartmatch operator ~~. I personally don't like it, but it would have done exactly what you want. Commented Jan 6, 2017 at 9:07
  • print "@astreams\n"; gives: jatm5_INT jatm5_APPL jatm5_JAVA jatm5_RLS jatm5_EDAG jatm5_REC now I want in fact perform a negative search and tell only if some $stream_s means some string doesn't exist in the array, some owner from some CC Baseline must be changed otherwise nothing to do. Commented Jan 6, 2017 at 10:01
  • I honestly don't have much experience with Perl but some times I have to write simple scripts to make easy my work. thx for your support Commented Jan 6, 2017 at 10:07

3 Answers 3

4

If you want to find all elements in the array that match the pattern, the grep builtin in Perl is your friend.

my @matches = grep { /$stream_s/ } @astreams;

This will try to match each element against the pattern /$stream_s/ and let through only the ones that contain $stream_s. Those end up in your new array.

If you want to reverse this and find all the elements in @astreams that do not match a certain pattern, you just negate the match.

my @not_matched = grep { ! /$stream_s/ } @astreams;

Here's a full example:

use strict;
use warnings;
use Data::Dumper;

my @astreams = qw(
    jatm5_INT jatm5_APPL jatm5_JAVA
    jatm5_RLS jatm5_EDAG jatm5_REC
    5_ASDF
);

my $stream_s = 'jat';

my @not_matched = grep { !/$stream_s/ } @astreams;

print Dumper \@not_matched;

This will output

$VAR1 = [
          '5_ASDF'
        ];

To just do something if any of them doesn't match, but you don't care which one that is, you can use grep inside an if, where its return value will be evaluated in scalar context. That means, the if will look at the number of elements returned by grep. If that is not 0, it is considered a true value and the check passes and the block will be entered.

if ( grep { /$stream_s/ } @astreams ) {
    # we found a match, do stuff
} else {
    # no match, do something else
}

You can of course also turn that around. All three forms below are equivalent.

if ( ! grep { /$stream_s/ } @astreams ) {
     # no match, do something
}

if ( not grep { /$stream_s/ } @astreams ) {
     # no match, do something
}

unless ( grep { /$stream_s/ } @astreams ) {
     # no match, do something
}

Note that your matching will check if any element in @stream contains (or does not contain) $stream_s.

my $stream_s = 'a';
my @astreams = qw(
    jatm5_INT jatm5_APPL jatm5_JAVA
    jatm5_RLS jatm5_EDAG jatm5_REC
    5_ASDF 5_ASDF_FOOBAR
);

In the above case, the first six elements contain an a somewhere. All of them will match.

my $stream_s = '5_';
my @astreams = qw(
    jatm5_INT jatm5_APPL jatm5_JAVA
    jatm5_RLS jatm5_EDAG jatm5_REC
    5_ASDF 5_ASDF_FOOBAR
);

In this example, all elements contain 5_.

my $stream_s = '5_ASDF';
my @astreams = qw(
    jatm5_INT jatm5_APPL jatm5_JAVA
    jatm5_RLS jatm5_EDAG jatm5_REC
    5_ASDF 5_ASDF_FOOBAR
);

Now the last two will match. If you don't want partial matches, but want to check for exactly that string, don't use a regular expression match.

my $stream_s = 'FOOBAR';
my @astreams = qw(
    jatm5_INT jatm5_APPL jatm5_JAVA
    jatm5_RLS jatm5_EDAG jatm5_REC
    5_ASDF 5_ASDF_FOOBAR
);

unless ( grep { $_ eq $stream_s } @astreams ) {
     # only go here if there is no element 'FOOBAR' in @astreams
}
Sign up to request clarification or add additional context in comments.

5 Comments

it is windows no grep posssible -:(
It is not Linux grep it is Perl grep which is platform independent. Both of them behaves quite differently.
@Adel as Arunesh says, this is not the Linux command grep, but it's a keyword in Perl. Just like if or foreach or print. All of those work on any operating system. There are some built-ins in Perl that do things that are OS specific, like say or gethostbyname, but Perl makes sure that it uses the right implementation under the hood so they will work on whatever OS you are, no matter if that's Windows or Linux or MacOS or Solaris or whatever else the Perl was compiled for.
OK but how to tall or to check that /$stream_s/ doesn't exist in @astreams;?
@AdelSALAH see my update, I just included that in the answer
3

The binding operator interprets its left argument in scalar context, so it makes no sense to use it on an array (unless you want to match the number of elements). Use a loop or an equivalent construct:

#! /usr/bin/perl
use warnings;
use strict;

use List::MoreUtils qw{ any };

my @astreams = qw( jatm5_INT jatm5_APPL jatm5_JAVA
                   jatm5_RLS jatm5_EDAG jatm5_REC );

my $stream_s = qr/EDA/;

print "Matched\n" if any { /$stream_s/ } @astreams;

2 Comments

Problem solved with this expression: if ( ! grep { /$stream_s/ } @astreams ) { # no match, do something } thx a lot.
@AdelSALAH: Note that it if there are several matches, it tries all of them.
0

This is more because TMTOWTDI than because I think this is a particularly good way to do it.

You could also interpolate the array as a string, and do a regex search on that.

if ( "@astreams" !~ /$stream_s/ )

Would match on all of the values that you're looking for, because "@astreams" interpolates to "jatm5_INTjatm5_APPLjatm5_JAVAjatm5_RLSjatm5_EDAGjatm5_REC" ... unfortunately, it will also match on strings like "EDAGjatm5".

if ( join( ' ', @astreams ) !~ /$stream_s/ )

Would probably do the right thing, assuming that $stream_s doesn't contain spaces. ... I wouldn't actually use this, because I want code that works, not code that probably works, but I think that it's instructive to think about the worse ways of doing things, and why they're not the best way.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.