I need to recursively rename every file and directory. I convert spaces to underscores and make all file/directory names to lowercase. How can I make the following script rename all files in one run? Currently the script needs to be run several times before all the files/directories are converted. The code is below:
#!/usr/bin/perl
use File::Find;
$input_file_dir = $ARGV[0];
sub process_file {
$clean_name=lc($_);
$clean_name=~s/\s/_/g;
rename($_,$clean_name);
print "file/dir name: $clean_name\n";
}
find(\&process_file, $input_file_dir);
if you are open to other approaches, here's a Python solution
You can rename files before traversing through a directory.
Or you could delay the renames until after traversal has occurred.
The problem you are encountering is because
find
finds directory"Abc Def"
find
callswanted("Abc Def")
rename "Abc Def" => "abc_def"
find
tries to enter"Abc Def"
, which does not exist anymoreso everything underneath does not get processed
You either need to specify
bydepth => 1
in the options you pass to find or callfinddepth
. From perldoc File::Find:However, you still need to decide how to deal with naming clashes because rename will clobber the target if the target exists.