29efe1b9 |
1 | #!/usr/bin/env perl |
2 | |
3 | # Perform multiple moves/copies. |
4 | |
5 | # Usage: multi mv 's/$/.old/' *.c |
6 | # multi cp 's:/tmp/(.*):$1:' * |
7 | # multi - svn mv - 's/foo/bar/' *foo* |
8 | # |
9 | # Options: -n don't actually do anything, just print what it would do |
10 | # -r reverse the arguments to each command |
11 | # -q don't print the commands as they are executed |
12 | |
13 | # Note that all variables in this script begin with a double |
14 | # underscore. This is because the <action> parameter is a piece of |
15 | # user-supplied Perl, which might perfectly legitimately want to |
16 | # define and use its own variables in the course of doing a complex |
17 | # transformation on file names. Thus, I arrange that all _my_ |
18 | # variables stay as far out of its likely namespace as they can. |
19 | |
20 | $__quiet = $__donothing = $__reverse = 0; |
21 | |
22 | while ($ARGV[0] =~ /^-(.+)$/) { |
23 | shift @ARGV; |
24 | $__quiet = 1, next if $1 eq "q"; |
25 | $__quiet = 0, $__donothing = 1, next if $1 eq "n"; |
26 | $__reverse = 1, next if $1 eq "r"; |
27 | } |
28 | |
29 | die "usage: multi <cmd> <action> <files>\n" . |
30 | " e.g. multi mv 'tr/A-Z/a-z/' *\n" if $#ARGV < 2; |
31 | " also: multi - <multiple-word-cmd> - <action> <files>\n" . |
32 | " or multi - svn mv - 'tr/A-Z/a-z/' *\n" if $#ARGV < 2; |
33 | |
34 | @__cmd = (); |
35 | if ($ARGV[0] eq "-") { |
36 | shift @ARGV; |
37 | while (defined $ARGV[0] and $ARGV[0] ne "-") { |
38 | push @__cmd, shift @ARGV; |
39 | } |
40 | if (!defined $ARGV[0]) { |
41 | die "multi: no terminating - in multiple-word command mode\n"; |
42 | } |
43 | shift @ARGV; # eat trailing - |
44 | } else { |
45 | $__cmd[0] = shift @ARGV; |
46 | } |
47 | $__action = shift @ARGV; |
48 | |
49 | while (@ARGV) { |
50 | $_ = $__origfile = shift @ARGV; |
51 | eval $__action; |
52 | $__newfile = $_; |
53 | ($__origfile, $__newfile) = ($__newfile, $__origfile) if $__reverse; |
54 | &pcmd(@__cmd, $__origfile, $__newfile) if !$__quiet; |
55 | system @__cmd, $__origfile, $__newfile if !$__donothing; |
56 | } |
57 | |
58 | sub pcmd { |
59 | my (@words) = @_; |
60 | printf "%s\n", join " ", map { &fmt($_) } @words; |
61 | } |
62 | |
63 | sub fmt { |
64 | local ($_) = @_; |
65 | if (/[ !"#$&'()*;<>?\\`|~]/) { |
66 | s/'/'\\''/g; |
67 | "'$_'"; |
68 | } else { |
69 | $_; |
70 | } |
71 | } |