#! /usr/bin/perl use strict ; use warnings ; my $X = 'X' ; my $prog = substr $0, rindex ( $0, '/' ) + 1 ; my $Usage = < option v : be verbose option q : be quiet option d : show debug info option f : action ; otherwise dry-run option X : treat string as pattern variable args : pattern where $X is variable like in: $prog $X.a $X.b Given `srcpat' A${X}B the `src' files are "A*B" Given `dst-pat' u${X}v and `src' == m/a(...)b/ then ( dst = src) =~ s/(${X})/u\${1}v/g example: mmv vhost.X X.conf : mv vhost.blib blib.conf : mv vhost.blob blob.conf : mv vhost.blab blab.conf USAGE sub Usage { die "$_[0]\n$Usage" ; } sub Error { die "Error $prog: $_[0]\n" ; } sub Warn { warn "$prog: $_[0]\n" ; } # usage: GetOptions(\%opt,ARG,ARG,..) defines $opt{ID} as 1 or user value # ARG = 'ID' | 'ID=SPC' | 'ID:SPC' for no-arg, required-arg or optional-arg # ID = perl identifier # SPC = i|f|s for integer, fixedpoint real or string argument use Getopt::Long ; Getopt::Long::config ( 'no_ignore_case' ) ; my %opt = () ; Usage '' unless GetOptions ( \%opt, qw(v q d f X=s) ) ; Usage("Arg count\n") unless @ARGV == 2 ; $Usage = < USAGE $X = $opt{X} if defined $opt{X} ; sub test_pat { my $p = shift ; 1 == scalar grep $_ eq $X, split /($X)/, $p ; } my $ARG0 = shift ; my $ARG1 = shift ; Error "not exactly 1 $X in src-pat $ARG0" unless test_pat $ARG0 ; Error "not exactly 1 $X in dst-pat $ARG1" unless test_pat $ARG1 ; my %MVS ; ( my $p0 = $ARG0 ) =~ s/$X/*/ ; my @SRC = <${p0}> ; Error "No files found for pattern $p0" unless @SRC ; printf "Sources:\n %s\n", join "\n ", @SRC if $opt{d} ; ( $p0 = $ARG0 ) =~ s/$X/(.*)/g ; for my $src ( @SRC ) { # sanity check Error "No match in $src for $p0" unless $src =~ /$p0/ ; my $match = $1 ; ( my $dst = $ARG1 ) =~ s/$X/$match/ ; Error "destination $dst already exists" if -e $dst ; $MVS { $src } = $dst ; } printf "Destinations:\n %s\n", join "\n ", values %MVS if $opt{d} ; print "Moves:\n" ; for my $src ( sort keys %MVS ) { printf " mv %s %s\n", $src, $MVS { $src } ; } for my $src ( sort keys %MVS ) { my $dst = $MVS { $src } ; Error "destination $dst already exists" if -e $dst ; if ( $opt{f} ) { print "rename $src $dst\n" ; rename $src, $dst or Error "can't rename $src $dst ($!)" ; } } print "*** This is a DRY-RUN ***\n" unless $opt{f} ;