Forum Moderators: coopster & phranque

Message Too Old, No Replies

Problem in Recursion

Recurse through a directory

         

crypto

9:31 am on Jan 8, 2004 (gmt 0)

10+ Year Member



Hi Everyone,

I'm a PHP programmer but trying my hands in PERL.
The script I'm trying to write recurses through
a directory and renames a particular file under
all it sub-directories. But the script I've written
just renames the file only in the first sub-directory
and stops recursing after that. Can anyone fix or
tell me whats going wrong? The piece of code
is as follows:

# Directory - (Specify your main directory below)
$dir = "/xyz";

# Filename - (Specify the name of the file that is to be renamed)
$fileToChange="old_file.txt";

# verify directory

if (-d $dir)
{
print "\nWorking Directory: $dir \n";
}
else
{
exit(0);
}

$newfilename = "new_file.txt";

# Call the recursive sub-routine to Rename the required file
renameOld($dir);

print "Rename Process completed.\n";

# Sub-routine to run a system command
sub runcmd
{
local($cmd)=$_[0];
system($cmd);
}

# define the renameOld sub-routine
sub renameOld
{
opendir(DIR,$_[0]);
while (($filename=readdir(DIR)))
{
if (($filename ne '.') && ($filename ne '..'))
{
if (-d "$_[0]/$filename")
{
renameOld("$_[0]/$filename");
}
elsif (-f "$_[0]/$filename")
{
if ($filename eq $fileToChange)
{
if ((-r "$_[0]/$filename") && (-w "$_[0]/$filename"))
{
runcmd("mv $_[0]/$filename $_[0]/$newfilename");
}
}
}
}
}
close DIR;
}

SeanW

3:53 pm on Jan 8, 2004 (gmt 0)

10+ Year Member



Couple of things.

Don't depend on @_/$_[0] always being there because it's implied by various functions. Pull out your function args as soon as you can:

my $dir = shift; # now use $dir instead $_[0]

Secondly, you've got some scoping problems with $filename... each time you recurse you're going to clobber $filename from the parent call. Use my or local to define it as a local variable.

Again, the DIR filehandle is getting stomped on successive recursions. Either define it locally as a reference, or pull out all the directories in array context before recursing:

opendir(DIR,$dir);
foreach my $filename (readdir(DIR)) { # doesn't matter what happens to DIR now

Sean

crypto

10:42 am on Jan 9, 2004 (gmt 0)

10+ Year Member



Yes thats what I did after scratching my head for some time. Making the variables local did the trick. Thanks anyways for the tips.