home *** CD-ROM | disk | FTP | other *** search
Korn shell script | 1997-08-26 | 4.1 KB | 156 lines |
- #!/bin/ksh
- # @(#) rename.ksh 1.3 95/01/23
- # 90/06/01 John DuBois (spcecdt@armory.com)
- # 91/02/25 Improved help info
- # 92/06/07 remove quotes from around shell pattern as required by new ksh
- # 94/05/10 Exit if no globbing chars given.
- # 95/01/23 Allow file set to be given on command line.
-
- lname=${0##*/}
- Usage="Usage: $lname [-htv] oldpattern newpattern [filename ...]"
- tell=false
- verbose=false
-
- while getopts :htv opt; do
- case $opt in
- h)
- echo \
- "$lname: rename files by changing parts of filenames that match a pattern.
- $Usage
- oldpattern and newpattern are subsets of sh filename patterns (the only
- globbing characters (wildcards) allowed are ? and *). All files that match
- oldpattern will be renamed with the filename characters that match the constant
- (non-globbing) characters of oldpattern changed to the corresponding constant
- characters of newpattern. The characters of the filename that match the
- globbing characters of oldpattern will be preserved. Globbing characters in
- oldpattern must occur in the same order in newpattern; for every globbing
- character in newpattern there must be an identical globbing character in
- oldpattern in the same sequence. Both arguments should be quoted since
- globbing characters are special to the shell. If filenames are given, only the
- named files are acted on; if not, all files that match oldpattern are acted on.
- Examples:
- rename \"/tmp/foo*.ba.?\" \"/tmp/new*x?\"
- All files in /tmp that match foo*.ba.? will have the \"foo\" part replaced by
- \"new\" and the \".ba.\" part replaced by \"x\". For example,
- /tmp/fooblah.ba.baz would be renamed to /tmp/newblahxbaz
- rename \* \*- foo bar baz
- foo, bar, and baz will be renamed to foo-, bar-, and baz-.
- Options:
- -h: Print this help.
- -v: Show the file move commands being executed.
- -t: Show what file moves would be done, but do not execute them."
- exit 0
- ;;
- t)
- tell=true
- ;;
- v)
- verbose=true
- ;;
- +?)
- print -u2 "$lname: options should not be preceded by a '+'."
- exit 1
- ;;
- :)
- print -r -u2 -- \
- "$lname: Option '$OPTARG' requires a value. Use -h for help."
- exit 1
- ;;
- ?)
- print -u2 "$lname: $OPTARG: bad option. Use -h for help."
- exit 1
- ;;
- esac
- done
-
- # remove args that were options
- let OPTIND=OPTIND-1
- shift $OPTIND
-
- oldpat=$1
- newpat=$2
-
- case $# in
- [01])
- print -u2 "$Usage\nUse -h for help."
- exit 1
- ;;
- 2)
- set -- $1
- if [[ ! -a $1 ]]; then
- echo "No files match $oldpat."
- exit
- fi
- ;;
- *)
- shift 2
- ;;
- esac
-
- typeset -i i=1 j
-
- # For old ksh
- # while [[ "$oldpat" = *'[\*\?]'* ]]; do
-
- # Example oldpat: foo*.a
- # Example newpat: bar*.b
-
- # Examples given for first iteration (in the example, the only interation)
- while [[ "$oldpat" = *[\*\?]* ]]; do
- # Get leftmost globbing pattern in oldpat
- pat=${oldpat#*[\*\?]} # pat=.a
- pat=${oldpat%%"$pat"} # pat=foo*
- pat=${pat##*[!\?\*]} # pat=*
- # Find parts before & after pattern
- oldpre[i]=${oldpat%%"$pat"*} # oldpre[1]=foo
- oldsuf[i]=${oldpat#*"$pat"} # oldsuf[1]=.a
- newpre[i]=${newpat%%"$pat"*} # newpre[1]=bar
- # Get rid of processed part of patterns
- oldpat=${oldpat#${oldpre[i]}"$pat"} # oldpat=.a
- newpat=${newpat#${newpre[i]}"$pat"} # newpat=.b
- let i=i+1
- done
-
- if [ i -eq 1 ]; then
- print -u2 "No globbing chars in pattern."
- exit 1
- fi
-
- oldpre[i]=${oldpat%%"$pat"*} # oldpre[2]=.a
- oldsuf[i]=${oldpat#*"$pat"} # oldsuf[2]=.a
- newpre[i]=${newpat%%"$pat"*} # newpre[2]=.b
-
- if $verbose; then
- j=1
- while [[ j -le i ]]; do
- echo \
- "Old prefix: ${oldpre[j]} Old suffix: ${oldsuf[j]} New prefix: ${newpre[j]}"
- let j=j+1
- done
- fi
-
- # Example file: foox.a
-
- for file; do
- j=1
- origname=$file # origname=foox.a
- newfile=
- while [[ j -le i ]]; do
- # Peel off a prefix interation 1 2
- file=${file#${oldpre[j]}} # file=x.a file=
- # Save the part of this prefix that is to be retained
- const=${file%${oldsuf[j]}} # const=x const=
- newfile=$newfile${newpre[j]}$const # newfile=barx newfile=barx.b
- file=${file#$const} # file=.a file=.a
- let j=j+1
- done
- if $tell; then
- echo "Would move: $origname -> $newfile"
- else
- if $verbose; then
- echo "Moving: $origname -> $newfile"
- fi
- mv $origname $newfile
- fi
- done
-