I am trying to write a perl script which checks all the directories in the current directory and then accordingly penetrates in the subsequent directories to the point where it contains the last directory. This is what I have written:
#!/usr/bin/perl -w
use strict;
my @files = <*>;
foreach my $file (@files){
if (-d $file){
my $cmd = qx |chown deep:deep $file|;
my $chdir = qx |cd $file|;
my @subfiles = <*>:
foreach my $ subfile(@subfiles){
if (-d $file){
my $cmd = qx |chown deep:deep $subfile|;
my $chdir = qx |cd $subfile|;
. # So, on in subdirectories
.
.
}
}
}
}
Now, some of the directories I have conatins around 50 sub directories. How can I penetrate through it without writing 50 if conditions? Please suggest. Thank you.
NOTE: The OS usually won't let you change ownership of a file or directory unless you are the superuser (i.e. root).
Now, we got that out of the way...
The
File::Find
module does what you want. Useuse warnings;
instead of-w
:The
File::Find
package imports afind
and afinddepth
subroutine into your Perl program.Both work pretty much the same. They both recurse deeply into your directory and both take as their first argument a subroutine that's used to operate on the found files, and list of directories to operate on.
The name of the file is placed in
$_
and you are placed in the directory of that file. That makes it easy to run the standard tests on the file. Here, I'm rejecting anything that's not a directory. It's one of the few places where I'll use$_
as the default.The full name of the file (from the directory you're searching is placed in
$File::Find::name
and the name of that file's directory is$File::Find::dir
.I prefer to put my subroutine embedded in my
find
, but you can also put a reference to another subroutine in there too. Both of these are more or less equivalent:In both of these, I'm gathering the names of all of the directories in my path and putting them in
@directories
. I like the first one because it keeps my wanted subroutine and myfind
together. Plus, the mysteriously undeclared@directories
in my subroutine doesn't look so mysterious and undeclared. I declaredmy @directories;
right above thefind
.By the way, this is how I usually use
find
. I find what I want, and place them into an array. Otherwise, you're stuck putting all of your code into your wanted subroutine.