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]

Reply via email to