Pete Emerson wrote: > > I just wrote my own version of your script. Not that it's better than > yours, just different. I've learned a lot from this list by seeing how > people do things differently than me! I hope you find my version helpful. > > A couple of notes about mine: > > 1) The directory is taken from the command line instead of prompting > when run. This means you can throw it in a cron job or the windows > equivalent, and it will run without human intervention. If a directory > is not specified, the current directory is assumed. Run it like this: > > rename.pl /path/to/dir > > 2) My regex makes sure that the -[0-9]-[0-9] (in the regex as -\d-\d) > comes before a .txt or .doc or some other three letter extension at the > end of the filename, per your description in your script. This makes > sure that the following files do NOT get renamed: > > bad-1-2filename.txt > bad-1-2.txtfilename.doc > bad-1-2.nota3letterextension > > 3) I decided to "warn" instead of "die" if a file cannot be renamed for > whatever reason. That way, you might have 1000 files that get renamed > and 1 that does not. Obviously, if you want to die if there are any > failures, the warn can be changed into a die, but note that you still > might have successfully renamed some files before the die occurs. The > downside to the warn is that if all of your files cannot be renamed, > then you're going to get a lot of error messages printed on the screen. > > 4) I'm using File::Find to get all of the filenames. My "return" in the > Rename subroutine can be removed if you want to do the renaming in all > subdirectories instead of just in the directory specified, although it's > probably a good idea to leave in the check (-f $old) to make sure we're > renaming a file and not a symlink or a directory. > > 5) I'm also doing a check to make sure that the new filename is > differently named than the old one by checking the success of the regex. > I don't think that renaming a file to it's own name will break anything, > but logically I like that in there. A performance gain or maybe even a > loss, perhaps, I don't know, but probably not worth caring about if > there is one.
Hi Pete, Just a couple of comments if you don't mind. (I knew you wouldn't :-) Don't skimp on the whitespace, it makes your code more readable. > #!/usr/bin/perl -w > > use strict; > use File::Find; > > my $dir=$ARGV[0]; > $dir='.' if (!defined $dir); > die "$dir is not a valid directory." if (!-d $dir); > $dir=~s#/$##; > > find(\&Rename, $dir); > ########################################## > sub Rename { > my $old=$File::Find::name; > return if ((!-f $old) or ($old=~m#$dir/\S+/#)); The expression ($old=~m#$dir/\S+/#) implies that you only want files in the $dir directory however File::Find::find() will still search through all the files and subdirectories below $dir. If you only want the files in $dir it would be better to use opendir/readdir/closedir or glob. Also the regular expression m#$dir/\S+/# might not do what you expect it to do. If the $dir variable contains any regex meta characters it could fail or match something that you did not expect. If the subdirectory name after $dir/ contains any space characters it will not match. > my $new=$old; > if ($new=~s/-\d-\d(\.\S{3})$/$1/) { > rename $File::Find::name, $new or warn "Could not rename > $File::Find::name: $!"; > } > } Due to way some file systems work I would store the file names in an array and use the array to rename the files instead of renaming them in the File::Find::find() sub. John -- use Perl; program fulfillment -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]