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

I need a fastest way to only find the filenames in the directory that has a particular pattern in perl.

for example, just like in unix command line, get me the filename under /root/ that has the pattern

grep -l Pattern /root/*.txt
Output is
foo.txt

Replies are listed 'Best First'.
Re: Find filename that has the pattern in a directory
by graff (Chancellor) on Jul 02, 2011 at 01:29 UTC
    I need a fastest way to only find the filenames in the directory that has a particular pattern in perl.

    Based on the rest of the OP, I think what you mean is "... find the names of the files in which the file data contains a match to a particular perl regex". Do I have that right?

    Some versions of the unix/linux "grep" tool provide an option to apply Perl regex syntax, but it's not clear to me which version of the Perl regex engine would be implemented (i.e. what range of perlish regex extensions is available). If the particular OS you're using has an adequate version of the "grep" utility, then the fastest way to get the file name list you want is to use that version of "grep" at the shell command line, with the relevant option flag.

    Apart from that, the only alternative is for your perl script to open each file in the search space, and read the file contents until either (a) the target pattern is found (so you print that file name and move on), or (b) you reach end-of-file (so you just move on to the next file).

Re: Find filename that has the pattern in a directory
by Marshall (Canon) on Jul 01, 2011 at 16:52 UTC
    Adapt to your path and search pattern:
    opendir (DIR, "C:/temp") or die "unable to open C:/temp $!\n"; my @files2 = grep{/\.pl$/}readdir DIR; print join("\n",@files2),"\n";
    The above gets only the file names, if you want the full path, then my @files2 = map{"C:/temp/".$_}grep{/\.pl$/}readdir DIR; The glob operator can be used also albeit there are pitfalls as there are several different incompatible glob()'s out there.

    my @files = glob("C:/temp/*.pl"); print join("\n",@files),"\n"; #full paths
    update: if you want all the files in a directory, then
    opendir (DIR, "/root") or die "unable to open /root $!\n"; @all = grep{-f}readdir DIR;
    readdir returns all files. Directories are a special type of file. the files . and .. are files. The -f file test in the grep will filter the output down to all "normal" files (no directories or . and .. entries).

    Update: Well I think I mis-understood the question. I guess the question should have been:
    I want an efficient way to search through a directory and get a list of files, each of which contain a certain pattern. .
    I think using command line grep is just fine. What about that solution is not "fast enough" or "efficient enough" for the application? Are you having trouble capturing and using the output of the command line grep command? Is this a Windows box and you don't have grep. Please explain the problem further.

    Every file will have to be opened and read sequentially until either the desired pattern is found or EOF is reached - that is true no matter what you do. A Perl program can use a different regex syntax than the command line grep, but that was not even part of the question.

Re: Find filename that has the pattern in a directory
by Anonymous Monk on Jul 01, 2011 at 15:28 UTC