I'm new to Perl, learning on my own. I've wrote many scripts (utilities) for myself but never posted them online. I would really appreciate any feedback on this script before I post it on a forum.
The script takes list of files names on command line, writes the name list in tmp file and opens it with vi(m). After user is done renaming, it reads new names from tmp file and renames files accordingly. Script can also process symlinks, where it lists and renames the target file name and also updates the symlink to point to renamed file afterwards.
#!/usr/bin/perl -w
use strict;
use Getopt::Std;
use File::Temp qw( tempfile );
use File::Basename qw( basename dirname );
# HANDLING CMD ARGS
$Getopt::Std::STANDARD_HELP_VERSION = 1;
my $usage = \&main::HELP_MESSAGE;
my %opts;
sub main::VERSION_MESSAGE {
print "virename v0.1\n";
}
sub main::HELP_MESSAGE {
print << "EOF";
Usage:\n virename [OPTIONS] [file_names]
OPTIONS
-s act on symlink target (also update symlink)
-v be verbose
--help pirnt help and exit
--version version
EOF
}
if (@ARGV) {
getopts( 'vs', \%opts ) or $usage->();
}
else {
print "Not enough arguments!\n\n";
$usage->();
exit 1;
}
my ( @names, @new_names, %symlinks );
if ( $opts{s} ) {
for my $name (@ARGV) {
if ( my $target = readlink $name ) {
my $target_name = basename $target;
$symlinks{$target_name} = { 'symlink', $name, 'target', $target };
push @names, $target_name;
}
else {
push @names, $name;
}
}
}
else {
@names = @ARGV;
}
die "Nothing to rename!\n" unless @names;
my ( $tmp, $tmp_name ) = tempfile(); # Tmp file
print {$tmp} join "\n", @names; # Writing names to tmp file
if ( !system "vim $tmp_name 2>/dev/null" ) {
}
elsif ( !system 'vi', $tmp_name ) {
}
else { exit; }
seek $tmp, 0, 0;
chomp( @new_names = <$tmp> ); # Reading new names from tmp file
unlink $tmp_name; # Removing tmp file
exit if @names != @new_names;
#Renaming
for ( 0 .. $#names ) {
my ( $new_name, $old_name );
my $is_symlink = exists $symlinks{ $names[$_] };
if ( $opts{s} && $is_symlink ) {
$old_name = $symlinks{ $names[$_] }->{target};
$new_name = dirname($old_name) . q{/} . $new_names[$_];
}
else {
$old_name = $names[$_];
$new_name = $new_names[$_];
}
if ( -e $new_name ) { #Skip if file already exists
print "'$new_name' already exits!\n" if $opts{v};
}
elsif ( rename $old_name => $new_name ) {
if ( $opts{s} && $is_symlink ) {
my $symlink = $symlinks{ $names[$_] }->{symlink};
unlink $symlink; # Removing old symlink
symlink $new_name => $symlink # Creating new symlink
or warn "symlink: $!\n";
print "'$symlink': '$old_name' => '$new_name'" if $opts{v};
}
else {
print "'$old_name' => '$new_name'\n" if $opts{v};
}
}
else {
warn "failed to rename $old_name to $new_name: $!\n";
}
}
__END__