#!/usr/bin/env perl # Perform multiple moves/copies. # Usage: multi mv 's/$/.old/' *.c # multi cp 's:/tmp/(.*):$1:' * # multi - svn mv - 's/foo/bar/' *foo* # # Options: -n don't actually do anything, just print what it would do # -r reverse the arguments to each command # -q don't print the commands as they are executed # Note that all variables in this script begin with a double # underscore. This is because the parameter is a piece of # user-supplied Perl, which might perfectly legitimately want to # define and use its own variables in the course of doing a complex # transformation on file names. Thus, I arrange that all _my_ # variables stay as far out of its likely namespace as they can. $__quiet = $__donothing = $__reverse = 0; while ($ARGV[0] =~ /^-(.+)$/) { shift @ARGV; $__quiet = 1, next if $1 eq "q"; $__quiet = 0, $__donothing = 1, next if $1 eq "n"; $__reverse = 1, next if $1 eq "r"; } die "usage: multi \n" . " e.g. multi mv 'tr/A-Z/a-z/' *\n" if $#ARGV < 2; " also: multi - - \n" . " or multi - svn mv - 'tr/A-Z/a-z/' *\n" if $#ARGV < 2; @__cmd = (); if ($ARGV[0] eq "-") { shift @ARGV; while (defined $ARGV[0] and $ARGV[0] ne "-") { push @__cmd, shift @ARGV; } if (!defined $ARGV[0]) { die "multi: no terminating - in multiple-word command mode\n"; } shift @ARGV; # eat trailing - } else { $__cmd[0] = shift @ARGV; } $__action = shift @ARGV; while (@ARGV) { $_ = $__origfile = shift @ARGV; eval $__action; $__newfile = $_; ($__origfile, $__newfile) = ($__newfile, $__origfile) if $__reverse; &pcmd(@__cmd, $__origfile, $__newfile) if !$__quiet; system @__cmd, $__origfile, $__newfile if !$__donothing; } sub pcmd { my (@words) = @_; printf "%s\n", join " ", map { &fmt($_) } @words; } sub fmt { local ($_) = @_; if (/[ !"#$&'()*;<>?\\`|~]/) { s/'/'\\''/g; "'$_'"; } else { $_; } }