John
John

Reputation: 109

Perl Grepping from an Array

I need to grep a value from an array. For example i have a values

@a=('branches/Soft/a.txt', 'branches/Soft/h.cpp', branches/Main/utils.pl');

@Array = ('branches/Soft/a.txt', 'branches/Soft/h.cpp', branches/Main/utils.pl','branches/Soft/B2/c.tct', 'branches/Docs/A1/b.txt');

Now, i need to loop @a and find each value matches to @Array. For Example

Upvotes: 0

Views: 2113

Answers (4)

John
John

Reputation: 109

This Solved My Question. Thanks to all especially @zdim for the valuable time and support

   my @SVNFILES = ('branches/Soft/a.txt', 'branches/Soft/b.txt');
   my @paths = ('branches/Soft/a.txt', 'branches/Soft/b.txt',
'branches/Docs/A1/b.txt', 'branches/Soft/B2/c.tct');

            foreach my $svn (@SVNFILES)
            {
            chomp ($svn);
            my $m = grep { /$svn/ } (@paths);

                            if ( $m eq '0' ) {
                            print "Files Mismatch\n";
                            exit 1;
                            }

            }

Upvotes: 0

zdim
zdim

Reputation: 66873

It works for me with grep. You'd do it the exact same way as in the More::ListUtils example below, except for having grep instead of any. You can also shorten it to

 my $got_it  = grep { /$str/ } @paths;
 my @matches = grep { /$str/ } @paths;

This by default tests with /m against $_, each element of the list in turn. The $str and @paths are the same as below.


You can use the module More::ListUtils as well. Its function any returns true/false depending on whether the condition in the block is satisfied for any element in the list, ie. whether there was a match in this case.

use warnings;   
use strict;

use Most::ListUtils;

my $str = 'branches/Soft/a.txt';

my @paths = ('branches/Soft/a.txt', 'branches/Soft/b.txt',
    'branches/Docs/A1/b.txt', 'branches/Soft/B2/c.tct');

my $got_match = any { $_ =~ m/$str/ } @paths;

With the list above, containing the $str, the $got_match is 1.

Or you can roll it by hand and catch the match as well

foreach my $p (@paths) {
    print "Found it: $1\n" if $p =~ m/($str)/;
}

This does print out the match.

Note that the strings you show in your example do not contain the one to match. I added it to my list for a test. Without it in the list no match is found in either of the examples.


To test for more than one string, with the added sample

my @strings = ('branches/Soft/a.txt', 'branches/Soft/h.cpp', 'branches/Main/utils.pl');
my @paths = ('branches/Soft/a.txt', 'branches/Soft/h.cpp', 'branches/Main/utils.pl',
     'branches/Soft/B2/c.tct', 'branches/Docs/A1/b.txt');

foreach my $str (@strings) {
    foreach my $p (@paths) {
        print "Found it: $1\n" if $p =~ m/($str)/;
    }
    # Or, instead of the foreach loop above use
    # my $match = grep { /$str/ } @paths;
    # print "Matched for $str\n" if $match;
}

This prints

Found it: branches/Soft/a.txt
Found it: branches/Soft/h.cpp
Found it: branches/Main/utils.pl

When the lines with grep are uncommented and foreach ones commented out I get the corresponding prints for the same strings.

Upvotes: 2

PerlDuck
PerlDuck

Reputation: 5720

The slashes dot in $a will pose a problem so you either have to escape them it when doing regex match or use a simple eq to find the matches:

Regex match with $a escaped:

my @matches = grep { /\Q$a\E/ } @array;

Simple comparison with "equals":

my @matches = grep { $_ eq $a } @array;

With your sample data both will give an empty array @matches because there is no match.

Upvotes: 1

quemeraisc
quemeraisc

Reputation: 492

You should escape characters like '/' and '.' in any regex when you need it as a character.

Likewise :

$a="branches\/Soft\/a\.txt"

Retry whatever you did with either grep or perl with that. If it still doesn't work, tell us precisely what you tried.

Upvotes: -1

Related Questions