On 28 Oct 1998, in message <[EMAIL PROTECTED]>
Tony Nugent <[EMAIL PROTECTED]> wrote:
| [I love talking to myself:-]
Oh please! Let me talk to you too!
| > On Sat Oct 24 1998 20:06, Coran Fisher aka The Doctor wrote:
| > There's more than one way to do this. An example might be useful:
| > % find /usr/include -follow -name \*.h | xargs grep time /dev/null
|
| I just had cause to do something similar to this, but it involved editing a
| whole bunch of html files to replace all instances of a URL address with
| another. While I was at it I also wanted to add a "background" image to
| the <BODY> tag.
I hope you put in a BGCOLOR tag as well. If the image is slow to load or
fails to load, you page will look pretty wonky. I usually pick a BGCOLOR
matching the average colour of the BACKGROUND image. Don't get me started on
forgetting the TEXT and LINK colours as well...
| Pretty boring job to do by hand, one file at a time.
|
| I thought about using sed, but I'd have to do it from a shell script (or
| bash function) because I'd have to filter each file, save the output
| into a temporary file, then copy this over the top of the original one.
| Tricky and messy.
But very tractable. I append "bsed" (batch sed) a wrapper for sed which does
exactly this. I use it all the time. One of the most useful things I've ever
written.
| But then perl came to the rescue...
| % find . -name \*.html -print | \
| xargs perl -pi 's/<BODY>/<BODY background=mat3.jpg>/i'
| Magical stuff, eh? :)
Not as magical as you might hope. Like cvs, "perl -i" makes a _new_ file,
moving the old one aside.
- this breaks hard links
- this trashes the file permissions (resets them per your umask)
This simple issue makes me never use the -i option to perl.
Bsed takes care to do it right. Install it and enjoy.
--
Cameron Simpson, DoD#743 [EMAIL PROTECTED] http://www.zip.com.au/~cs/
#!/bin/sh
#
# bsed - batch edit with sed
# - Cameron Simpson <[EMAIL PROTECTED]>
#
cmd=`basename "$0"`
usage="Usage: $cmd [-v] [-i suf] {-f script|{-e sedcmd}...|sedcmd}... [--] files...
-v Verbose.
+v Not verbose.
-i suf Copy original to original.suf if changed.
-f script Passed to sed.
-e sedcmd Passed to sed.
sedcmd Passed to sed."
fflag=
diff='diff -u'
sedscript=
ecmd=
[ -t 1 ] && verbose=1 || verbose=
ibak=
set x $BSEDOPTS ${1+"$@"}; shift
badopts=
while :
do
case $1 in
--) shift ; break ;;
-v) verbose=1 ;;
+v) verbose= ;;
-f) fflag=1; sedscript=$2; shift ;;
-i) ibak=$2; shift ;;
-i?*) ibak=`expr "x$1" : 'x-i\(.*\)'` ;;
-e) ecmd="$ecmd
$2"; shift ;;
-*) echo "$cmd: $1: unknown option" >&2
badopts=1
;;
*) break ;;
esac
shift
done
sedf=sed
if [ $fflag ]
then
sedf="$sedf -f \"\$sedscript\""
else
if [ -z "$ecmd" ]
then
case $# in
0) echo "$cmd: missing sed command" >&2
badopts=1
;;
*) ecmd=$1; shift ;;
esac
fi
sedf="$sedf -e \"\$ecmd\""
fi
[ $# = 0 ] && { echo "$cmd: missing filenames" >&2; badopts=1; }
[ $badopts ] && { echo "$usage" >&2; exit 2; }
tmp=/tmp/$cmd.$$
trap 'rm -f "$tmp"; exit 1' 1 2 15
xit=0
ok=1
while [ $ok ] || xit=1 # catch exit from previous loop
[ $# -gt 0 ] # loop condition
do
file=$1; shift
if [ "x$file" = x- ]
then
[ $verbose ] && echo "reading filenames from stdin..."
set x `cat` ${1+"$@"}; shift
continue
fi
ok=
if [ ! -f "$file" ]
then
echo "$cmd: $file: not a regular file, skipped" >&2
continue
fi
bakfile= bakdir=
case "$ibak" in
'') ;;
*/) case "$file" in
*/*) bfile=`basename "$file"`
dfile=`dirname "$file"`
;;
*) bfile=$file
dfile=.
esac
bakdir=$dfile/$ibak
bakfile=$bakdir/$bfile
;;
*) bakfile=$file.$ibak
;;
esac
if [ -n "$bakfile" ] && [ -f "$bakfile" ]
then
echo "$cmd: $file: backup $bakfile already exists, original unchanged" >&2
continue
fi
[ $verbose ] && echo "$file ..."
if eval "$sedf <\"\$file\" >\$tmp"
then
# check for changes
if cmp -s "$file" "$tmp"
then
ok=1 # no change
continue
else
if [ ! -s "$tmp" ]
then
echo "$cmd: warning: tmpfile empty! skipping $file" >&2
continue
fi
fi
[ $verbose ] && $diff "$file" "$tmp"
# ensure we have a backup
if [ -n "$bakfile" ]
then
if [ -f "$bakfile" ]
then
echo "$cmd: $file: backup $bakfile already exists, original unchanged"
>&2
continue
fi
if cp "$file" "$bakfile" && cmp -s "$file" "$bakfile"
then :
else echo "$cmd: $file: can't make backup, original unchanged" >&2
continue
fi
fi
# copy change version in
if cat "$tmp" > "$file" && cmp -s "$tmp" "$file"
then
ok=1 # backup & update ok
continue
fi
echo "$cmd: $file: can't update" >&2
if [ -n "$bakfile" ]
then
if cat "$bakfile" > "$file"
then
echo "$cmd: $file: original restored" >&2
rm "$bakfile"
else
echo "$cmd: $file: restore failed; original left in $bakfile" >&2
fi
else
echo "$cmd: $file: no backup, may be corrupt" >&2
fi
else
echo "$cmd: $file: edit fails; original unchanged" >&2
fi
done
rm -f "$tmp"
exit $xit