#!/bin/bash # $Id: temp,v 0.5 2005/05/01 21:22:49 jpeek Exp $ # # temp - rename files as backups # Usage: temp [-v] name [names...] # # This script renames one or more files in the same way that # the GNU utilities cp(1), mv(1), and ln(1) make backup files. # For instance, a file foo would be renamed to foo.~1~, foo.~2~, # or whatever; the script finds the highest-numbered existing # backup file and renames a file with the next-higher suffix. # # We match up to 999 backups. This limit can be changed by # adding more patterns to the "for try in" line below and # be editing the sanity check block "if ((parseB >= 999))". # # Written for bash version 2.05 with the hope that it'll be # upward-compatible. Notice the #!/bin/bash line above. # This script uses bash-specific features. # Placed in the public domain by Jerry Peek, 1 May 2005. # Use of this script, and any problems you have, is your own # responsibility. If you do adapt it, I'd appreciate being # mentioned. If you have comments or improvements, please # send them to me: see http://www.jpeek.com/contact.html. myname=${0##*/} # basename of this script (no leading path) case "$1" in -v|--verbose) vflag=yes shift ;; esac for file do if [[ ! -e $file ]] then echo "$myname: aborting: can't find '$file'" 1>&2 exit 1 fi # Find all existing backups of $file. cp(1) makes a backup with # a suffix number one higher than the highest-numbered backup, # so we do the same. # # Set nullglob option so if file* doesn't match, we remove pattern. # # Using a series of glob patterns like this has the effect of # sorting the files numerically by suffix. It checks for suffix # numbers up to 999. To check higher suffixes, add more patterns. # This is a hack but it avoids parsing and piping to sort(1). # (Also note the check for 999 in the nested "if" statement below.) shopt -s nullglob highest= for try in $file.~[0-9]~ $file.~[1-9][0-9]~ $file.~[1-9][0-9][0-9]~ do highest="$try" done # If we found a backup file, get highest suffix. Else use 1: if [ -n "$highest" ] then parseA=${highest%*~} # filename without the last tilde parseB=${parseA##*~} # remove all but the numeric suffix if ((parseB >= 999)) then echo "$myname: aborting: won't rename '$file' with suffix above 999." 1>&2 exit 1 else let suffix=parseB+1 fi else suffix=1 fi newname="$file.~$suffix~" # Handle -v option: test "$vflag" == yes && echo "$myname: renaming '$file' to '$newname'" 1>&2 # Use -i as a double-check, abort on non-zero return: mv -i "$file" "$newname" || exit 1 # Update timestamp so file won't be removed too soon # by a cron job that checks last-modification time: touch "$newname" done