Need a file renaming facility

Brian Hunt hunt at csli.STANFORD.EDU
Fri Apr 29 00:24:35 AEST 1988


In article <3564 at fluke.COM> inc at tc.fluke.COM (Gary Benson) writes:
>What I'm looking for is a general-purpose
>renaming facility that (I hope) takes wild cards, with this kind of synatax:
>
>    rename -f QT.?.r.pre QT.?.r
>
>	      -or-
>
>    rename QT.*.r.pre QT.*.r

This may be overkill, but here's a shell script I've been using for
some time to do often complicated renaming of multiple files.  It's
probably rather clumsy, but has worked quite well for me.  I'm sure
there are many possibilties I haven't tried, though, so USE AT YOUR
OWN RISK.  I just added the part that passes flags to mv(1), so that
bit is relatively untested.  I'm sure it has a relatively limited set
of characters it can handle in a filename; one possibly unexpected
character it will choke on is ':', since that's what the script uses
as the delimiter for the sed(1) substitution function.  Beats choking
on '/', at least...

The syntax is as follows:

rename [-flags] "exp1" "exp2"

where exp1 describes the files to be renamed using the wildcards '?'
and '*', and exp2 gives the pattern for the new names of the files
using the same sequence of wildcards as exp1.  For example,

rename -i "a*b?*c" "x*?y*z"

would use "mv -i" to move files a12b345c and a1b2c to x123y45z and
x12yz, respectively, while leaving the file a12bc unchanged.  That is,
each wildcard in exp2 is replaced by the string which was matched by
the corresponding wildcard in exp1.  In addition, if a wildcard in
exp2 is preceded by a tilde, the corresponding string is dropped from
the destination filename (possibly making it non-unique.)  So,

rename "*.*" "*~*"

would move files a.b, a.c, and b.c to a, a, and b respectively, thus
losing the contents of a.b.  Probably best to always use -i option
when using this feature...

Note that the arguments to rename must be quoted somehow in order for
the wildcards not to be globbed away.  To save me from worrying about
this, I have the following in my .cshrc:

alias ren 'rename -i "\!:1" "\!:2"'

At most nine wildcards are allowed.  All filename changes are echoed
on the standard output.

Finally, here is the script.  Feel free to use, copy, and modify it
as you please, with or without attribution; i.e., it's all yours...

Brian Hunt
Dept. of Mathematics
Stanford University

#!/bin/csh -f
set noglob
set flags
while (`echo "$1" | cut -c1` == "-")
	set flags=($flags $1)
	shift
end
if (`echo "$1" | sed 's:[^?*]::g'` != `echo "$2" | sed 's:[^?*]::g'`) then
	echo "rename:  Please use same wildcards in both arguments."
	exit 1
endif
unset noglob
set files=$1
set noglob
set oldexp=`echo "$1" | sed -e 's:?:\\(.\\):g' -e 's:\*:\\(.*\\):g'`
set newexp="$2"
foreach digit (1 2 3 4 5 6 7 8 9)
	set tmpexp=`echo "$newexp" | sed 's:[?*]:\\'"$digit":`
	if ("$tmpexp" == "$newexp") then
		break
	else
		set newexp="$tmpexp"
	endif
end
if (`echo "$newexp" | grep -c '[?*]'` > 0) then
	echo "rename:  Too many wildcards."
	exit 2
endif
set newexp=`echo "$tmpexp" | sed 's:~\\[1-9]::g'`
foreach oldfile ($files)
	set newfile=`echo "$oldfile" | sed s:^"$oldexp"\$:"$newexp":`
	echo "moving $oldfile to $newfile"
	mv $flags "$oldfile" "$newfile"
end
exit 0



More information about the Comp.unix.questions mailing list