?
Solved

Need to search for files in all subfolders

Posted on 2000-03-09
8
Medium Priority
?
880 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
[X]
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
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
Technology Partners: 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

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
 
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 600 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

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

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

There are many situations when we need to display the data in sorted order. For example: Student details by name or by rank or by total marks etc. If you are working on data driven based projects then you will use sorting techniques very frequently.…
Checking the Alert Log in AWS RDS Oracle can be a pain through their user interface.  I made a script to download the Alert Log, look for errors, and email me the trace files.  In this article I'll describe what I did and share my script.
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…
Six Sigma Control Plans

770 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