A handy script for moving (renaming) files.
#!/usr/bin/perl
=head1 Author: Martin (bumby) Stenberg
Name: emv
Description: Rename files using $EDITOR
Start date: 2010-07-30
Last updated Date: 2010-07-30
=cut
use File::Temp qw/tmpnam tempfile/;
use File::Basename;
use File::Copy;
use Data::Dumper;
use Getopt::Std;
use Env qw/EDITOR/;
use strict;
my $help = <<EOF;
Usage: emv [OPTION] FILES
Rename FILES using \$EDITOR ($EDITOR).
-h Display this help message
-p Pretend to rename files, don't actually do it
The script handles overwriting name changes such as "a -> b; b -> a" w
+hich
means you can swap two filenames by swapping their line positions:
a.txt
b.txt
to
b.txt
a.txt
EOF
my %opts;
getopts( 'hp', \%opts );
die $help if $opts{h};
chomp(@ARGV = <STDIN>) unless @ARGV;
# write file names to temporary file
my ($fh, $file) = tmpnam() or die "Error: Could not create temporary f
+ile: $!\n";
print $fh $_,"\n" for @ARGV;
close($fh);
# open file name list in $EDITOR
system($EDITOR, $file);
# read in new file names
open(FILE, $file) or die "Error: Could not open temporary file: $!\n";
my @NEWNAMES = ();
chomp(@NEWNAMES = <FILE>);
close(FILE);
unlink($file);
die "Erro: File names does not align. Please do not add or remove line
+s while renaming files in $EDITOR.\n" if $#ARGV != $#NEWNAMES;
my %files = ();
for(my $i=0; $i < @NEWNAMES; $i++) {
$files{$ARGV[$i]} = $NEWNAMES[$i];
}
foreach my $fname (keys %files) {
next if $fname eq $files{$fname}; # skip unchanged names
# handle overwriting name changes, e.g: a -> b; b -> a
if(exists $files{$files{$fname}}) {
my (undef, $tmpfile) = tempfile(DIR => dirname($files{$fname})
+ ,OPEN => 0);
mv($files{$fname}, $tmpfile);
mv($fname, $files{$fname});
mv($tmpfile, $fname);
delete $files{$files{$fname}};
} else {
mv($fname, $files{$fname}) if $fname and exists $files{$fname}
+;
}
}
sub mv {
my ($from, $to) = @_;
if($opts{p}) {
print "$from -> $to", "\n";
}else {
move($from, $to);
}
}