bruce01
bruce01

Reputation: 93

Match multiple elements of array Perl

I am using File::Find to search over dirs. I then want to use @ARGV to match terms the user inputs. I only want the first to second last elements to be used for matching (last is an output name). I though my code would work but it isn't, any ideas?

if ($File::Find::name =~ m/$_/ for @ARGV[0..-2]){
    #manipulate filenames
}

Thanks.

Upvotes: 0

Views: 388

Answers (2)

TLP
TLP

Reputation: 67940

Why would you use $File::Find::name here? That's the relative path and not just the file name. I assume you are trying to match file names here. Here's what you do:

my $output = pop @ARGV;             # now you can use @ARGV freely
my $regex  = join "|",              # join by alternations
                 map quotemeta,     # disable meta characters
                 @ARGV;             # list of file names
find(sub { 
        /$regex/i or return;        # quick check
        # manipulate files...
     }, $dir);

There are tweaks you can do, such as disable meta characters or not, using case insensitivity or not /.../i.

Documentation: pop, join, quotemeta

Upvotes: 3

amon
amon

Reputation: 57656

The EXPR for LIST is a statement, not an expression. if (COND) {BLOCK} expects COND to be an expression.

You can embed a block into an expression via do {BLOCK}, but this won't quite do what you want.

If you want to express “manipulate filename if any item of the list matches”, do

if (grep { $File::Find::name =~ /$_/ } LIST) { ... }

If you want to express “manipulate filename if all items of the list match”, do

if (not grep { not $File::Find::name =~ /$_/ } LIST) { ... }

You cannot slice an array like @array[0..-2] as the range operator isn't special in array subscripts; the range from 0 to -2 is empty. Rather: @array[0 .. @array-2].

Upvotes: 1

Related Questions