Need to search for files in all subfolders

Posted on 2000-03-09
Last Modified: 2008-03-17
I am totally new to PERL.
We are running a PERL/WIN32 on an IIS. I need a script to seach all subfolders for a specific file type.

This is a sample for searching one directory I found.
opendir(USERDIR, "$root_dir") || open_error("$root_dir");
@DIRS = readdir(USERDIR);

foreach $dir(sort(@DIRS)) {

$dir =~ s/^\.*//;

if (-d "$root_dir$dir") {  # test for files (no folders)

opendir(USERDIR, "$root_dir$dir");
@FILES = readdir(USERDIR);

foreach $file(sort(@FILES)) {

if ("$root_dir$file" =~ /htm/) {
$found_file = "$dir/$file";
$found_file =~ s/^\///;
print "$root_dir$found_file<BR>\n";

How must I change it?

Thanks in advance!
Question by:zzconsumer
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
  • 2
  • +1

Author Comment

ID: 2600666
Adjusted points to 200
LVL 16

Expert Comment

ID: 2600769
here is a smaller solution. it is based on the DOS dir command, so you dont have to worry about a lot of PERL code.
print "Usage: $0 file pattern.\n E.g. \t$0 c:\\*.pl \n\t$0 *.txt c:\windows\*.dll\n" if $#ARGV<0;

foreach $pattern (@ARGV){
  $ans=`dir /b/s $pattern`; ## Get the subdirectory listing for the pattern sepcified
  @ans=split(/\n/,$ans);  ##  Store each line as an element of an array
  print "Searching for $pattern\n\n";
        print $_,"\n";  ## Print every line of the array
  print "=================================================================\n";

Author Comment

ID: 2600986
Err... thanks a lot!
I don't understand anything of the script but it looks cool... ;)

I did not have a chance to get it to work. (I'm sure I'm too stupid for PERL. Or I just need some docs.)
The main thing is that I have a presentation tomorrow, and the script must run. Don't you see any chance just to change the existing script? The point is this is only a part of the script and I need to change some more subroutines. This may last too long if I need to know what I'm doing... ;)
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

LVL 16

Expert Comment

ID: 2601059
ok here is what the script does.
Rather than reinventing the wheel and writing a code in PERL that would recursively goes thru the directories and searches for a file/file pattern, i am calling the DOS dir command from within PERL (dir /s/b file_pattern).

By saving on the recursive part of the program i can now concentrate on processing the incoming results. In the above script i am just storing them in an array and printing them one-by-one. You can choose to do anything that you want with these files by adding code after foreach(@ans){ .

ideally i would have preferred that you use the script i have provided, but i can understand your situation. i will look at the script today and try to come up with a solution, but i cant guarantee on the time :( due to my other professional commitments.

Hope that helps

Expert Comment

ID: 2601796
Your initial script didnot traverse recursively. I put together a sub so we can do recursive call to it. I did it under Linux, you just need to change the / to \, I guess.
#! /usr/bin/perl -w
my $root_dir = "/home/zyu/.www";
my @files = ();
my @zeros = ();
my $found_file;
my $debug = 1;

@files = &AllFilesUnderAdir($root_dir, @zeros);

foreach $file (@files) {
    if ($file =~ /\.htm/) {
        $found_file = $file;
        $found_file =~ s/^\///;
        print "$found_file<BR>\n";
exit 0;

sub AllFilesUnderAdir() {
    my ($root, @list) = @_;
    my (@filesAtRoot, $dirEntry);
    opendir ROOTDIR, $root or ($debug and print STDERR "Err: Failed to open $root: $!" && return @list);
    @filesAtRoot = grep !/^\.\.?$/, readdir ROOTDIR;
    close ROOTDIR;
    foreach $dirEntry (@filesAtRoot) {
        if ( -f $dirEntry ) { push @list, $dirEntry}
        elsif ( -d $dirEntry ) { @list = &AllFilesUnderAdir($dirEntry, @list) }
        else { $debug and print "Donno what it is: $dirEntry. a symlink?\n"; }
    $debug and print "root=$root    files under it totals: ", $#list+1, "\n";
    return @list

Accepted Solution

omere earned 200 total points
ID: 2601951
No need for such long code, this is why the File::find module is there.

Example searches $dirname for *.htm (files only) recursively:

use File::Find;
sub doit {
  /\.htm/ && -f && print "$_\n";
$dirname = "c:/"; # note forward slash
find(\&doit, $dirname);

or an obvious one-liner:

use File::Find;
find sub { /\.htm/ && -f && print "$_\n"; } , @ARGV; # pass a parameter

Expert Comment

ID: 2601959
I forgot to mention that if you want to print the full pathname of the file it's in $File::Find::name (also see $File::Find::dir).

Author Comment

ID: 2620915
Thanks a lot to all of you! I had to decide which solution to use, used omere's, slightly changed.
However, my presentation was successful.

Featured Post

[Webinar] Code, Load, and Grow

Managing multiple websites, servers, applications, and security on a daily basis? Join us for a webinar on May 25th to learn how to simplify administration and management of virtual hosts for IT admins, create a secure environment, and deploy code more effectively and frequently.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

I've just discovered very important differences between Windows an Unix formats in Perl,at least 5.xx.. MOST IMPORTANT: Use Unix file format while saving Your script. otherwise it will have ^M s or smth likely weird in the EOL, Then DO NOT use m…
Many time we need to work with multiple files all together. If its windows system then we can use some GUI based editor to accomplish our task. But what if you are on putty or have only CLI(Command Line Interface) as an option to  edit your files. I…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…

737 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question