-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Added one-line program description to -h output - Improved cleanup after pod2html - Minor reformatting
- Loading branch information
Showing
2 changed files
with
92 additions
and
96 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,10 @@ | ||
#!/usr/bin/env perl | ||
$^W = 1; | ||
use warnings; | ||
use strict; | ||
|
||
# mved - carefully rename multiple files | ||
# | ||
# Copyright (C) 1997-2003 raf <[email protected]> | ||
# Copyright (C) 1997-2006 raf <[email protected]> | ||
# | ||
# This program is free software; you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
|
@@ -21,7 +21,7 @@ use strict; | |
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
# or visit http://www.gnu.org/copyleft/gpl.html | ||
# | ||
# 20030901 raf <[email protected]> | ||
# 20060124 raf <[email protected]> | ||
|
||
=head1 NAME | ||
|
||
|
@@ -45,36 +45,35 @@ I<mved> - carefully rename multiple files | |
|
||
=head1 DESCRIPTION | ||
|
||
I<mved> renames multiple files. The C<source> argument is a filename | ||
glob specifying the set of files to rename. The C<target> argument is a | ||
pattern specifying the new names for the set of files. The C<source> | ||
argument can contain all of the normal shell globbing constructs (C<?>, | ||
C<*> and C<[...]>) as well as C<=> which is a synonym for C<*>. If any | ||
normal shell globbing constructs are used, they must be quoted to | ||
prevent the shell from performing filename expansion. This is not | ||
necessary when the only construct used is C<=>. There are two styles of | ||
C<target> argument. One allows C<=> to represent the text matching the | ||
(positionally) corresponding glob construct in the C<source> argument. | ||
The other allows C<=#=> (where C<#> is an integer) to represent the text | ||
matching the C<#-th> glob construct in the C<source> argument. The two | ||
styles cannot be mixed. | ||
|
||
I<mved> creates new links to the existing files. If the C<-v> verbose | ||
option is supplied, the corresponding I<mv> commands are printed. If any | ||
of them fail, they are all unlinked and the operation is aborted. If all | ||
were successful, the original files are unlinked. | ||
|
||
Before renaming any files, I<mved> checks for any dubious consequences. | ||
If a source filename is equal to its corresponding target filename, that | ||
(redundant) renaming operation is skipped. The user is informed unless | ||
the C<-q> quiet option is supplied. If a source filename is equal to | ||
some other target filename, I<mved> gets nervous and exits unless the | ||
C<-f> force option is supplied. If the same filename is a target for | ||
multiple source filenames, I<mved> exits unless the C<-f> force option | ||
is supplied. If any file to be created already exists, I<mved> exits | ||
unless the C<-f> force option is supplied. B<When forced, mved will | ||
unlink any existing target files>. The user will be informed unless the | ||
C<-q> quiet option is supplied. | ||
I<mved> renames multiple files. The C<src> argument is a filename glob | ||
specifying the set of files to rename. The C<dst> argument is a pattern | ||
specifying the new names for the set of files. The C<src> argument can | ||
contain all of the normal shell globbing constructs (C<?>, C<*> and | ||
C<[...]>) as well as C<=> which is a synonym for C<*>. If any normal shell | ||
globbing constructs are used, they must be quoted to prevent the shell from | ||
performing filename expansion. This is not necessary when the only construct | ||
used is C<=>. There are two styles of C<dst> argument. One allows C<=> to | ||
represent the text matching the (positionally) corresponding glob construct | ||
in the C<src> argument. The other allows C<=#=> (where C<#> is an integer) | ||
to represent the text matching the C<#-th> glob construct in the C<src> | ||
argument. The two styles cannot be mixed. | ||
|
||
I<mved> creates new links to the existing files. If the C<-v> verbose option | ||
is supplied, the corresponding I<mv> commands are printed. If any of them | ||
fail, they are all unlinked and the operation is aborted. If all were | ||
successful, the original files are unlinked. | ||
|
||
Before renaming any files, I<mved> checks for any dubious consequences. If a | ||
source filename is equal to its corresponding destination filename, that | ||
(redundant) renaming operation is skipped. The user is informed unless the | ||
C<-q> quiet option is supplied. If a source filename is equal to some other | ||
destination filename, I<mved> gets nervous and exits unless the C<-f> force | ||
option is supplied. If the same filename is a destination for multiple | ||
source filenames, I<mved> exits unless the C<-f> force option is supplied. | ||
If any file to be created already exists, I<mved> exits unless the C<-f> | ||
force option is supplied. B<When forced, mved will unlink any existing | ||
destination files>. The user will be informed unless the C<-q> quiet option | ||
is supplied. | ||
|
||
=head1 OPTIONS | ||
|
||
|
@@ -106,41 +105,40 @@ manpage properly with a command like: | |
|
||
=item C<-n> | ||
|
||
Don't rename anything. Just print the corresponding I<mv> commands and | ||
(and possibly I<rm> commands) then exit. | ||
Don't rename anything. Just print the corresponding I<mv> commands and (and | ||
possibly I<rm> commands) then exit. | ||
|
||
=item C<-f> | ||
|
||
Force I<mved> to obey even when it doesn't like what you are doing. B<If | ||
you force mved to rename a file to an existing file, the existing file | ||
will be unlinked first>. Never use this without using C<-n> first to see | ||
what you are telling I<mved> to do and verifying that it is what you | ||
really, really want to do. | ||
Force I<mved> to obey even when it doesn't like what you are doing. B<If you | ||
force mved to rename a file to an existing file, the existing file will be | ||
unlinked first>. Never use this without using C<-n> first to see what you | ||
are telling I<mved> to do and verifying that it is what you really, really | ||
want to do. | ||
|
||
=item C<-q> | ||
|
||
Don't print "Skipping filename" messages when a source filename matches | ||
it's corresponding target filename. Don't print "Unlinking filename" | ||
Don't print "Skipping filename" messages when a source filename matches it's | ||
corresponding destination filename. Don't print "Unlinking filename" | ||
messages when forced to unlink existing files. | ||
|
||
=item C<-v> | ||
|
||
Print corresponding I<mv> commands when renaming each file. Implied by | ||
the C<-d> option. | ||
Print corresponding I<mv> commands when renaming each file. Implied by the | ||
C<-d> option. | ||
|
||
=item C<-d> | ||
|
||
Print debugging messages that show the C<source> and C<target> arguments | ||
before and after translation from filename globs into regular | ||
expressions. Also print corresponding I<mv> commands when renaming each | ||
file. | ||
Print debugging messages that show the C<src> and C<dst> arguments before | ||
and after translation from filename globs into regular expressions. Also | ||
print corresponding I<mv> commands when renaming each file. | ||
|
||
=item C<-b #> | ||
|
||
Specify how many backslashes to count backwards when determining whether | ||
or not special characters are quoted. The default is 4 which should be | ||
more than you'll ever need (unless you have files with consecutive | ||
backslashes in their names - shudder). | ||
Specify how many backslashes to count backwards when determining whether or | ||
not special characters are quoted. The default is 4 which should be more | ||
than you'll ever need (unless you have files with consecutive backslashes in | ||
their names - shudder). | ||
|
||
=back | ||
|
||
|
@@ -185,13 +183,14 @@ backslashes in their names - shudder). | |
|
||
=head1 RETURNS | ||
|
||
I<mved> returns 0 (zero) upon success, 1 (one) upon failure. Upon | ||
failure, no files will have been renamed. | ||
I<mved> returns 0 (zero) upon success, 1 (one) upon failure. Upon failure, | ||
no files will have been renamed. | ||
|
||
=head1 BUGS | ||
|
||
Hard links are used so it is impossible to I<mved> files from one file | ||
system to another. Use I<mv> for this. Then rename with I<mved>. | ||
system to another. Use I<mv> for this. Then rename with I<mved>. This is not | ||
really a bug. It is a safety feature. | ||
|
||
Doesn't handle patterns containing pipe C<'|'> characters because this | ||
character is used as the regular expression separator. | ||
|
@@ -206,17 +205,17 @@ Released under the terms of the GPL (http://www.gnu.org/copyleft/gpl.html) | |
|
||
=head1 HISTORY | ||
|
||
Many years ago on a MIPS far away, there was a program called I<mved> | ||
that renamed multiple files using C<=>. It was very useful but I haven't | ||
seen it since. | ||
Many years ago on a MIPS far away, there was a program called I<mved> that | ||
renamed multiple files using C<=>. It was very useful but I haven't seen it | ||
since. | ||
|
||
=head1 SEE ALSO | ||
|
||
I<link(2)>, I<unlink(2)>, I<mv(1)>, I<rm(1)> | ||
|
||
=head1 AUTHOR | ||
|
||
20030901 raf <[email protected]> | ||
20060124 raf <[email protected]> | ||
|
||
=head1 URL | ||
|
||
|
@@ -241,7 +240,8 @@ sub help | |
" -v - Print equivalent mv commands (implied by -d)\n", | ||
" -d - Print debugging messages\n", | ||
" -b # - Set depth of quote characters to check (default 4)\n", | ||
"\n"; | ||
"\n", | ||
"Mved carefully renames multiple files.\n"; | ||
exit; | ||
} | ||
|
||
|
@@ -262,21 +262,19 @@ sub nroff | |
sub html | ||
{ | ||
system "pod2html --noindex $0"; | ||
unlink 'pod2html-dircache', 'pod2html-itemcache'; | ||
unlink glob 'pod2htm*'; | ||
exit; | ||
} | ||
|
||
my %opt; | ||
use Getopt::Std; | ||
help() unless getopts('hmwrnfqvdb:', \%opt); | ||
help() if exists $opt{h}; | ||
man() if exists $opt{m}; | ||
nroff() if exists $opt{r}; | ||
html() if exists $opt{w}; | ||
help() unless $#ARGV == 1; | ||
|
||
my $src_glob = $ARGV[0]; | ||
my $dst_glob = $ARGV[1]; | ||
help if !getopts('hmwrnfqvdb:', \%opt) || exists $opt{h}; | ||
man if exists $opt{m}; | ||
nroff if exists $opt{r}; | ||
html if exists $opt{w}; | ||
help unless @ARGV == 2; | ||
my $src_glob = shift; | ||
my $dst_glob = shift; | ||
my $testing = exists $opt{n}; | ||
my $force = exists $opt{f}; | ||
my $quiet = exists $opt{q}; | ||
|
@@ -286,17 +284,17 @@ my $backwards = exists $opt{b} ? $opt{b} : 4; | |
|
||
print "$name: glob $src_glob $dst_glob\n" if $debug; | ||
|
||
# construct a glob and get the list of matching files | ||
# Construct a glob and get the list of matching files | ||
|
||
$src_glob =~ s/=/*/g; | ||
my @src = glob($src_glob); | ||
die "$name: No such file: $src_glob\n" if $#src == -1; | ||
my @src = glob $src_glob ; | ||
die "$name: No such file: $src_glob\n" unless @src; | ||
|
||
# translate src into a regular expression search | ||
# Translate src into a regular expression search | ||
|
||
my $src_re = $src_glob; | ||
my $unsloshed = ''; | ||
$unsloshed = "(?<!" . $unsloshed . "\\\\)" for 1 .. $backwards; | ||
$unsloshed = "(?<!" . $unsloshed . "\\\\)" for 1..$backwards; | ||
my $head = qr/(?:\^|!)/; | ||
my $char = qr/(?:[^\]]|\\.)/; | ||
my $body_part = qr/(?::\w+:|$char-$char|$char)/; | ||
|
@@ -320,7 +318,7 @@ for my $rep (@rep) | |
$src_re =~ s/^/^/; | ||
$src_re =~ s/$/\$/; | ||
|
||
# translate dst into a regular expression replacement | ||
# Translate dst into a regular expression replacement | ||
|
||
my $dst_re = $dst_glob; | ||
my $explicit_target = qr/$unsloshed=(\d+)=/; | ||
|
@@ -342,7 +340,7 @@ else | |
print "$name: re s|$src_re|$dst_re|\n" if $debug; | ||
die "pattern contains '|'\n" if $src_re =~ /\|/ || $dst_re =~ /\|/; | ||
|
||
# construct the list of dst file names | ||
# Construct the list of dst file names | ||
|
||
my @dst; | ||
my $old; | ||
|
@@ -355,18 +353,18 @@ for $old (@src) | |
push @dst, $new; | ||
} | ||
|
||
# must be ultra paranoid but helpful | ||
# Must be ultra paranoid but helpful | ||
|
||
my $help = "Use -n to check and then -f to force it iff you are certain"; | ||
|
||
my %dst_chk; | ||
for (my $i = 0; $i <= $#dst; ++$i) | ||
for (my $i = 0; $i < @dst; ++$i) | ||
{ | ||
die "$name: Aborting: target $dst[$i] appears multiple times\n" if !$testing && !$force && exists $dst_chk{$dst[$i]}; | ||
$dst_chk{$dst[$i]} = $i; | ||
} | ||
|
||
for (my $i = 0; $i <= $#src; ++$i) | ||
for (my $i = 0; $i < @src; ++$i) | ||
{ | ||
if (exists $dst_chk{$src[$i]}) | ||
{ | ||
|
@@ -385,31 +383,31 @@ for (my $i = 0; $i <= $#src; ++$i) | |
} | ||
} | ||
|
||
for (my $i = 0; $i <= $#dst; ++$i) | ||
for (my $i = 0; $i < @dst; ++$i) | ||
{ | ||
die "$name: Aborting: $dst[$i] already exists\n$help\n" | ||
if -e $dst[$i] && !$testing && !$force; | ||
} | ||
|
||
# if testing, print out corresponding mv commands then exit | ||
# If testing, print out corresponding mv commands then exit | ||
|
||
if ($testing) | ||
{ | ||
for (my $i = 0; $i <= $#src; ++$i) | ||
for (my $i = 0; $i < @src; ++$i) | ||
{ | ||
my $r = (-d $dst[$i]) ? 'r' : ''; | ||
print "rm -${r}f ", $dst[$i], ' (if forced)', "\n" if -e $dst[$i]; | ||
print 'mv ', $src[$i], ' ', $dst[$i], "\n"; | ||
} | ||
|
||
exit(0); | ||
exit; | ||
} | ||
|
||
# if forced, first unlink any existing destination files :[ | ||
# If forced, first unlink any existing destination files :[ | ||
|
||
if ($force) | ||
{ | ||
for (my $i = 0; $i <= $#src; ++$i) | ||
for (my $i = 0; $i < @src; ++$i) | ||
{ | ||
if (-d $dst[$i]) | ||
{ | ||
|
@@ -424,10 +422,10 @@ if ($force) | |
} | ||
} | ||
|
||
# try to move all of the files | ||
# Try to move all of the files | ||
|
||
my $i; | ||
for ($i = 0; $i <= $#src; ++$i) | ||
for ($i = 0; $i < @src; ++$i) | ||
{ | ||
print "mv $src[$i] $dst[$i]\n" if $verbose; | ||
|
||
|
@@ -441,11 +439,11 @@ for ($i = 0; $i <= $#src; ++$i) | |
} | ||
} | ||
|
||
# if any failed, abandon and remove all destination files | ||
# If any failed, abandon and remove all destination files | ||
|
||
if ($i != $#src + 1) | ||
if ($i != @src) | ||
{ | ||
for ($i = 0; $i <= $#src; ++$i) | ||
for ($i = 0; $i < @src; ++$i) | ||
{ | ||
if (-d $dst[$i]) | ||
{ | ||
|
@@ -460,10 +458,8 @@ if ($i != $#src + 1) | |
die "$name: Aborting: Failed to mv $src[$i] $dst[$i] ($!)\n"; | ||
} | ||
|
||
# otherwise, remove the originals | ||
# Otherwise, remove the originals | ||
|
||
unlink @src; | ||
|
||
exit; | ||
|
||
# vi:set ts=4 sw=4: |