Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

SOLVED: Subroutine to Search Subdirectories Failing at Filehandle Test

by BJ_Covert_Action (Beadle)
on Apr 02, 2009 at 22:06 UTC ( #755132=perlquestion: print w/replies, xml ) Need Help??

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

Hello Monks,

I am attempting to code a subroutine that allows me to scour through a given directory and all subdirectories. This is going to be a small piece of a much larger project so, even though what I am doing within those subdirectories seems trivial, it will be changed later. Anyways, here is the folder tree I am working in:

>Search_Dir.plx
>TryMe (directory)
->I_Am_$$
->Some$$
->Not_Found
->TryMe2 (dir)
-->Copy Of I_Am_$$
-->Copy Of Some$$
-->Copy Of Not_Found
->TryMe3 (dir)
-->Copy2 of I_Am_$$
-->Copy2 of Some$$
-->Copy of Not_Found


Each of the files with the (dir) following it is a subdirectory the (dir) is just a tag posted here, it is not in the actual names of the subdirectories.

I am trying to run Search_Dir.plx to go through this file tree and print to output.txt a list of all of the filenames that contain $$ (again, seems trivial, but this is because I am building up to stuff).

So here is what the contents of Search_Dir.plx look like now:

#!/usr/bin/perl # Search_Dir.plx use warnings; use strict; open OUTPUT, ">output.txt"; print "Please input the path to a directory you would like to search: +"; chomp(my $dir_name = <STDIN>); opendir DIR, $dir_name or die "Couldn't open the specified directory: +$!"; search_dir($dir_name); sub search_dir{ my $sub_name = shift; opendir SUB, $sub_name or die "Couldn't open the specified directo +ry: $!"; while(my $file = readdir(SUB)){ next if $file eq "." or $file eq ".."; next if $file eq "output.txt"; print $file, "\n"; if(-d $file){ search_dir($file); }elsif($file =~ /\$\$/){ print OUTPUT "Possible \$\$ file found: $file\n"; } } #close SUB; }


So when I run the script I tell it to search through the TryMe directory. It seems to find the first two $$ files successfully and print them to output.txt. However, it does not seem to get into the subdirectory logic at all. That is, when I feed it the logic:

if(-d $file){ search_dir($file); }elsif($file =~ /\$\$/){ print OUTPUT "Possible LIST\$\$ file found: $file\n"; }


...the -d $file sections seems to always return false. At first I thought that the problem came from calling the subroutine from within itself. However, to troubleshoot, I just put a generic print "Here\n"; statement within that same section of the if statement (-d $file) and nothing ever printed. So I guess my final question is, why isn't my subroutine detecting the subdirectories within the file tree. Or, for that matter, why isn't the -d test returning true?

Also, as a disclaimer, I know there is a module that handles this kind of thing called File::Find. However, part of the reason I am trying to code this is just as a learning exercise. Furthermore, I want some customize-ability for where I am going to use this subroutine later. So despite there being an existing module, I would still like to work this out using file and directory handles and the readdir command myself (same goes for grep function).

Let me know if there is anything else anyone needs to assess this problem. I am working on a Windows XP machine with the strawberry perl 5.10 distribution.

Thank you in advance,
Brady

Replies are listed 'Best First'.
Re: Subroutine to Search Subdirectories Failing at Filehandle Test
by ikegami (Pope) on Apr 02, 2009 at 22:16 UTC

    readdir returns an unqualified file name, so when you use -d, you are looking in the current directory for a file that's in another directory.

    You should consider using File::Find::Rule or similar.

Re: Subroutine to Search Subdirectories Failing at Filehandle Test
by Perlbotics (Chancellor) on Apr 02, 2009 at 22:24 UTC

    Two changes fixed this:

    sub search_dir{ my $sub_name = shift; local *SUB; # <---- 1st: In order to have a new *SUB for each recu +rsion... opendir SUB, $sub_name or die "Couldn't open the specified directo +ry: $!"; while(my $file = readdir(SUB)){ next if $file eq "." or $file eq ".."; next if $file eq "output.txt"; $file = "$sub_name/$file"; # <---- 2nd: since you didn't chdir +... print $file, "\n"; if(-d $file){ search_dir($file); }elsif($file =~ /\$\$/){ print OUTPUT "Possible \$\$ file found: $file\n"; } } #close SUB; }
    As ikegami already said, File::Find is your friend.

      Beautiful. It worked like a charm. Thank you oh so very much friends.

      Cheers.

Re: Subroutine to Search Subdirectories Failing at Filehandle Test
by smanicka (Scribe) on Apr 03, 2009 at 16:33 UTC
    I'm not sure if this code will help , but i have used file find to perform a force copy of every file present inside a set of directories and the sub directories to another directory.These folders have pictures in them which have been sorted and reside in individual sub directories .for eg.
    folder1 |-nature | |-animals | |-sky | | |-night | | |-day | | |-silouttes | |-flowers |-cars
    and everything gets moved in bin mode to another single folder.
    #!usr/bin/perl use strict; use File::Find; use File::Copy; my @location=("C:/folder1","C:/folder2"); my $new_location="C:/moved_files"; foreach my $location(@location){ print "\n$location\n"; find(\&force_move,$location); } sub force_move(){ my $file=$_; print "\n $file"; my $out = "$new_location/$file"; if (-d "$file"){ } else { if ($file ne "."){ open (OUTBIN, '>',"$out") || die "unable to open $out"; binmode(OUTBIN) || die "unable to set binmode $out"; print "\n$out\n"; } } } print "I am done!!!!"; sleep(2);
      Actually, that is useful. I am chipping through the perldoc info on file::find now. Thanks for the help so far though everyone, it is definitely helping me learn a lot (which is really the final goal of anything anyways).

      Cheers.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://755132]
Approved by ikegami
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (4)
As of 2019-11-12 03:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Strict and warnings: which comes first?



    Results (64 votes). Check out past polls.

    Notices?