简体   繁体   中英

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.

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

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] .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM