[Gllug] error in bash script to rename files in a directory

Tethys tet at accucard.com
Mon Dec 30 00:42:35 UTC 2002


"Liam Delahunty" writes:

>rename phpp php *.phpp
>
>Then in vi I did the following for each of the files to sort out the
>internal links.
> :1,$s/php3/php/g
>
>However, I'm sorry, but for me that's still not as quick or easy as a DOS
>rename and
>then an extended search and replace in Home Site, but I might get the hang
>of this Linux lark yet... ;)

True, it's not. But the DOS rename only works because the DOS command
prompt doesn't expand wildcards. Contrast that with Unix shells that
expand wildcards before passing the arguments to the command. The
DOS way may seem intuitive but actually it's precisely the opposite.
Because wildcards are handled by the application, they're completely
inconsitent between applications and even, as in the case of rename,
within a single application! The only reason "rename *.php3 *.php"
seems obvious is purely learned behaviour. The first * is a filename
wildcard, the second is a placeholder in a replace pattern.

But, it's easy enough to come up with something that behaves like the
DOS rename if that's what you want. Here's one I've just knocked up.
It uses "%" instead of "*" as the wildcard character, and has the added
bonus that you can have multiple wildcards per rename. Usage is:

	dosrename %.php3 %.php
	dosrename %foo%.bar my_%_foofile_%.bar

A more thorough implementation would catch the few pathalogical corner
cases that trip up this one, but in common use, this should do pretty
much everything you want.

Tet

-------------- next part --------------
#!/bin/sh

### Print a usage message
pusage()
{
	(
		echo "usage: $prog src dst"
		echo "  src and dst are patterns with % being a wildcard character"
		echo "  src and dst must contain the same number of wildcards"
	) 1>&2
}

prog=`basename "$0"`

if [ $# -ne 2 ]
then
	pusage
	exit 1
fi

src_wildcards=`echo "$1" | sed 's/[^%]//g' | wc -c`
dst_wildcards=`echo "$2" | sed 's/[^%]//g' | wc -c`

if [ $src_wildcards -ne $dst_wildcards -o $src_wildcards -lt 2 ]
then
	pusage
	exit 1
fi

srclist=`echo "$1" | sed 's/%/*/g'`

for file in $srclist
do  
	count=1
	srcpatt="$1"
	dstfile="$2"
	while [ $count -lt $dst_wildcards ]
	do  
		srcre=`echo "$srcpatt" | \
			sed -e 's/\./\\\\./g' -e 's,%,\\\\(.*\\\\),' -e 's/%/\.*/g'`
		subst=`echo "$file" | sed "s/$srcre/\1/"`
		srcpatt=`echo "$srcpatt" | sed "s/%/$subst/"`
		dstfile=`echo "$dstfile" | sed "s/%/$subst/"`
		
		count=`expr $count + 1`
	done
	
	mv "$file" "$dstfile"
done


More information about the GLLUG mailing list