My advice is do not attempt renaming but first generate a list of moves and then review that list
See similar questions Changing filenames, Multiple File Rename
So, I would start with a program like
#!/usr/bin/perl --
use strict; use warnings;
use Data::Dump qw/ dd pp /;
use File::Basename qw/ fileparse /;
use File::Copy qw/ move /; # RENAME
Main( @ARGV );
exit( 0 );
sub Main {
my @files = qw'
err/error.txt
GridSquare_0000000077_FoilHole_0000000001_Data_0000000002_20120315_103
+721.jpg
GridSquare_0000000077_FoilHole_0000000001_Data_0000000002_20120315_103
+721.xml
blah_foo.jpg
blah_bar.xml
blah/foo.jpg
blah/bar.xml
';
my @rename = makeRenameList( @files );
fakeRename( @rename );
}
sub fakeRename {
print "\n";
for my $name ( @_ ){
print "rename ", pp( $name ), "\n\n";
}
}
sub makeRenameList {
my @fromTo;
my %rename_index = (
qw/ .jpg 1 .xml 1 /
);
LOOP_FROMFILE:
for my $fromFile ( @_ ){
my($directory, $filename, $suffix) = $fromFile =~ m{^(.*?)(?:
+([^/]*?)(\.[^\.]*))?$};
if( not exists $rename_index{lc $suffix} ){
warn "Unknown suffix ($suffix) ignoring($fromFile)";
next LOOP_FROMFILE;
}
my $toFile = join '',
$directory,
$rename_index{lc $suffix}++,
$suffix;
push @fromTo, [ $fromFile, $toFile ];
}
return @fromTo;
}
__END__
Which would print
Unknown suffix (.txt) ignoring(err/error.txt) at - line 41.
rename [
"GridSquare_0000000077_FoilHole_0000000001_Data_0000000002_20120315_
+103721.jpg",
"1.jpg",
]
rename [
"GridSquare_0000000077_FoilHole_0000000001_Data_0000000002_20120315_
+103721.xml",
"1.xml",
]
rename ["blah_foo.jpg", "2.jpg"]
rename ["blah_bar.xml", "2.xml"]
rename ["blah/foo.jpg", "blah/3.jpg"]
rename ["blah/bar.xml", "blah/3.xml"]
Next I might change sub makeRenameList to
my $transform = "";
$transform = \&transformJpg if $suffix =~ /^\.(jpe|jpg|jpeg)/
+i ;
$transform = \&transformXml if $suffix =~ /^\.xml/i ;
if( not $transform ){
warn "Unknown suffix ($suffix) ignoring($fromFile)";
next LOOP_FROMFILE;
}
my $toFile = $transform->(
$fromFile,
$directory,
$filename,
$suffix,
$rename_index{lc $suffix}++
);
push @fromTo, [ $fromFile, $toFile ];
}
return @fromTo;
}
So that each file suffix gets its own transform function , like
sub transformJpg {
dd transformJpg => \@_ ;
my( $path, $dir, $file, $suffix, $idx ) = @_;
$file =~ s/^.(.*).$/$1/;
return "$dir$idx$suffix";
return $path;
}
sub transformXml {
dd transformXml => \@_ ;
my( $path, $dir, $file, $suffix, $idx ) = @_;
return "$dir$idx$suffix";
return $path;
}
and so on and so forth, until I'm satisfied with output of fakeRename, than I might call realRename :)