#!/usr/bin/perl -w # # $Revision: 1.8+1 $ $Date: 2010/01/05 17:45:59 $ # $Source: /home/vogelke/bin/RCS/rename,v $ # $UUID: 20e54287-6fc6-3ee3-84d7-21d209fe87a5 $ # #>> Don't forget the quotes! <<<\n"; exit(1); } sub mydie { print STDERR (@_, "\n"); $nodoit || exit(1); } sub unbrace { my ($x) = (@_); $x =~ s/\\\{/\(/; $x =~ s/\\\,/\|/g; $x =~ s/\\\}/\)/; return $x; } sub expand_udir { my ($fname) = @_; my ($flag, $uname) = ($fname =~ m!^(\~([^/]*))\/!); if ($flag) { if ($uname) { my ( $name, $passwd, $uid, $gid, $quota, $comment, $gcos, $dir, $shell ) = getpwnam($uname); $fname =~ s!^\~[^/]*\/!$dir\/!; } else { my ( $name, $passwd, $uid, $gid, $quota, $comment, $gcos, $dir, $shell ) = getpwuid($<); $fname =~ s!^\~\/!$dir\/!; } } return ($fname); } # First, scan for options. while (1) { ($op = shift) || &usage; ($op =~ /^-delete$/) && do { ($DeleteOK = 1); next; }; ($op =~ /^-s$/) && do { ($showpattern = 1); next; }; ($op =~ /^-n$/) && do { ($nodoit = 1); next; }; ($op =~ /^-copy$/) && do { ($copy = 1); next; }; ($op =~ /^-i$/) && do { ($interactive = 1); next; }; ($op =~ /^-e$/) && do { ($perlit = 1); next; }; # otherwise unshift(@ARGV, $op); last; } if ($perlit) { ($op = shift) || &usage; @files = @ARGV; if (!@files) { @files = ; chop(@files); } $showpattern && print STDERR ("Using perl expression \'$op\'\n"); } else { ($#ARGV != 1) && &usage; my ($spattern, $dpattern) = @ARGV; $spattern = &expand_udir($spattern); $dpattern = &expand_udir($dpattern); $spattern =~ m#^[^\*\?\{\}]*\/#; my $head = $&; if ($head) { my $newhead = <${head}>; if ($newhead ne $head) { print STDERR ("Replacing $head with $newhead.\n"); $spattern =~ s*^$head*$newhead*; } } $spattern =~ s/\W/\\$&/g; # Quote everything needing it. $spattern =~ s/(^|[^\\])\\\*/$1(.*)/g; # Turn wildcards into regexps $spattern =~ s/(^|[^\\])\\\?/$1(.)/g; $spattern =~ s/(^|[^\\])(\\\{\S+(\\\,\S+)+\\\})/ $1 . &unbrace($2) /eg; $dpattern =~ s/\W/\\$&/g; # Quote everthing needing it in destination. for (my $i = 1 ; ($dpattern =~ s/\\(\*|\?)/\${$i}/) ; $i++) { 1; } my $foo = $op; @files = <${foo}>; $op = "s/$spattern/$dpattern/"; $showpattern && print STDERR ("Using perl expression \'$op\'\n"); } my %seen = (); foreach (@files) { my $was = $_; eval $op; die $@ if $@; if ($seen{$_}) { &mydie("$was and $seen{$_} would both rename to $_."); } $seen{$_} = $was; $_ = $was; # Undo the change for the next pass. } $DeleteOK && print STDERR ">> Overwritting existing files is enabled (-d option).\n"; $nodoit && print STDERR ">> No changes will actually be made (-n option).\n"; FILE: for (@files) { my $was = $_; eval $op; die $@ if $@; if ($was eq $_) { print STDERR ("$was unchanged.\n"); } else { my $overwrite = (($DeleteOK && (-e $_)) ? ' (overwrite)' : ""); print STDOUT ("$was -> $_$overwrite\n"); if ($interactive) { QUERY: while (1) { my $input; print STDERR ("OK? "); (($input = ) =~ /^\s*y|yes/i) && last QUERY; ($input =~ /\s*n|no/i) && next FILE; } } if (!(-e $was)) { &mydie("Source file does not exist: $was"); } if (!$DeleteOK && (-e $_)) { &mydie("Target file exists: $_"); } elsif (!$nodoit) { $! = 0; if ($copy) { my $err; ($err = system("cp", "-p", $was, $_)) && ($! = ($err >> 8)) && &mydie("Could not copy: $!"); } else { rename($was, $_) || &mydie("Error while renaming: $!"); } } } } __END__ =head1 NAME rename - renames multiple files =head1 SYNOPSIS B I<[options] "spattern" "dpattern"> B I<[options]> -e I I<[files]> =head1 DESCRIPTION =over 10 =item I