Solved

Need to search for files in all subfolders

Posted on 2000-03-09
8
867 Views
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);
closedir(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);
closedir(USERDIR);

foreach $file(sort(@FILES)) {

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

How must I change it?

Thanks in advance!
0
Comment
Question by:zzconsumer
  • 3
  • 2
  • 2
  • +1
8 Comments
 
LVL 1

Author Comment

by:zzconsumer
ID: 2600666
Adjusted points to 200
0
 
LVL 16

Expert Comment

by:maneshr
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.

===========recurse.pl
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";
  foreach(@ans){
        print $_,"\n";  ## Print every line of the array
  }
  print "=================================================================\n";
}
0
 
LVL 1

Author Comment

by:zzconsumer
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... ;)
0
 
LVL 16

Expert Comment

by:maneshr
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
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 3

Expert Comment

by:jyu_88
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.
----------cut---------cut---------
#! /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) {
        $dirEntry=$root."/".$dirEntry;
        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
}
---------cut--------cut----------
0
 
LVL 1

Accepted Solution

by:
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
0
 
LVL 1

Expert Comment

by:omere
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).
0
 
LVL 1

Author Comment

by:zzconsumer
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.
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

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…
On Microsoft Windows, if  when you click or type the name of a .pl file, you get an error "is not recognized as an internal or external command, operable program or batch file", then this means you do not have the .pl file extension associated with …
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…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…

757 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

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now