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

Okay, I have a directory with a bunch of files. What I want to do is open the directory, and for each file whose name has BLAH in it, I want do do something to that file. What I have now is doing something to every file in the directory.
opendir(DIR, "$dir") || die "cant open dir.\n"; while (defined(my $file = readdir DIR) { do something; } closedir(DIR);
How can I narrow $file to only files with BLAH in the name?

Replies are listed 'Best First'.
(zdog) Re: How to pattern match filenames in readdir?
by zdog (Priest) on Jun 05, 2001 at 21:07 UTC
    Try this:
    opendir (DIR, "$dir") || die "cant open dir.\n"; my @files = grep { /BLAH/ } readdir (DIR); closedir (DIR); for (@files) { do something; }

    Zenon Zabinski | zdog | zdog7@hotmail.com

Re: How to pattern match filenames in readdir?
by chipmunk (Parson) on Jun 05, 2001 at 22:52 UTC
    Several of the solutions proposed so far have the disadvantage of reading in the entire contents of the directory, before iterating over the desired filenames. This could be an issue if the directory contains a lot of files.

    Here's a solution that reads in one filename at a time, as your original code does.

    opendir(DIR, "$dir") || die "can't open dir $dir: $!.\n"; while (defined(my $file = readdir DIR)) { next unless /BLAH/; do something; } closedir(DIR);
    The glob solution that runrig suggested, while (<*BLAH*>) {, also reads one filename at a time.

      Actually, most implementations of Perl's glob (yes, there are quite a few) compute the entire list of matches prior to returning the first match.

              - tye (but my friends call me "Tye")
Re: How to pattern match filenames in readdir?
by runrig (Abbot) on Jun 05, 2001 at 21:14 UTC
    If you don't need a complex regex, then globbing works too:
    while (<*BLAH*>) { my $file = $_; # Do stuff with file }
      I got the following to work:
      my @file = grep {/BLAH/} readdir (DIR); foreach $file @file { do something; }
      Thanks for your help!