#!/bin/sh # # changein # # AUTHOR: # Dan Harkless # # COPYRIGHT: # This file is Copyright (C) 2001 by Dan Harkless, and is released under the # GNU General Public License . # # USAGE: # % changein [...] '' '' # # DESCRIPTION: # Calls sed on multiple files to change one pattern to another in-place. # "perl -e 's///g' -i -p [...]" is a # better solution to this problem, but I didn't become aware of that # particular option combination until six years after starting this script. # Luckily I never got around to expending the energy to rewrite this shell # script as a more fault-tolerant (but grossly overwritten, I now realize) # Perl script. # # Oh well. I guess this script could still come in handy for someone on a # system without perl. It also reports whether is found or not # in each file processed, which can be handy sometimes. # # DATE MODIFICATION # ========== ================================================================== # 2001-10-23 Retired in favor of "perl -e 's///g' -i -p ". # 2001-04-04 While avoiding single-quoting on $old_pattern and $new_pattern on # "Changing..." message, need to double-quote to avoid globbing. # 2000-03-21 Oops. sed uses regexps by default -- we need to use egrep to see # if the file contains the pattern, not fgrep. # 1998-10-22 fgrep doesn't have a -q option everywhere: redirect to /dev/null. # 1998-07-13 Check if files are writable before trying to overwrite them. If # they're not, we'll just error and leave them to be done manually. # 1998-07-13 Only run sed on files that fgrep says contain , so we # don't change timestamps on files unnecessarily. # 1998-07-07 Doing `sed $expr $orig > $temp; mv $temp $orig` breaks hard links # and screws up permissions. To prevent this, instead do: # `cp $orig $temp; sed $expr $temp > $orig; rm $temp`. # 1997-08-21 Re-wrote as a sh script. Actually, I now realize this would be # easier and more fault-tolerant in Perl. # 1995-12-28 Original csh script. progname=`basename $0` # Make sure at least 3 parameters were passed. if [ $# -lt 3 ]; then echo "usage: $progname [...] '' ''" exit 1 fi # Shift off the files so that $1 and $2 are the old and new patterns. while [ $# -gt 2 ]; do files="$files $1" shift done old_pattern="$1" new_pattern="$2" # Check to see if the old or new patterns contain the character(s) we want to # use as the sed separator character. if [ `echo "$old_pattern $new_pattern" | fgrep -c @` = 0 ]; then sed_expr="s@$old_pattern@$new_pattern@g" elif [ `echo "$old_pattern $new_pattern" | fgrep -c \^` = 0 ]; then sed_expr="s^$old_pattern^$new_pattern^g" else echo "$progname: D'oh!!! Your pattern contains both a '@' and a '^'. " echo " changein needs an additional version of the sed call." exit 1 fi # egrep for the pattern in each file and run sed on those that contain it. for f in $files; do if egrep "$old_pattern" $f > /dev/null; then if [ -w $f ]; then echo $f": Changing '""$old_pattern""' to '""$new_pattern""'..." tempfile=$f-changein-$HOST-$$ trap "mv -f $tempfile $f" 1 2 3 15 cp -f -p $f $tempfile sed "$sed_expr" $tempfile > $f sed_status=$? if [ $sed_status = 0 ]; then rm -f $tempfile else mv -f $tempfile $f echo "$progname: Aborting." exit $sed_status fi else echo $f": **************** Not writable!!! Skipping!!! ****************" fi else echo $f": '"$old_pattern"' not found." fi done