FW: [Gllug] Awk Sed

Nix nix at esperi.demon.co.uk
Sun Dec 9 14:18:45 UTC 2001


On Fri, 7 Dec 2001, Kieran Barry moaned:
> On Fri, 7 Dec 2001, harry wrote:
>> Put the following in a shell script
>> #! /bin/sh
>> sed -e 's/'$2'/'$3'/g' $1 > $1ff; more $1ff > $1; rm $1ff; rm *~
>> 
> I was rather confused about the rm * here.  I misparsed "~" as some kind
> of quote...

The use of more in there is frankly bizarre, and it isn't robust against
a slash in $2 or $3.

... oh, and it odesn't work for multiple files, and it overwrites files
called $1ff.

>> Pass it something like
>> >$ ./harrysed textfile house maison
>> or
>> >$./harrysed sedscript.sh 's\/hte\/the\/'  's\/hte\/the\/g'
>> 
> This seems to work.  I'd be interested on style comments from real
> gurus...

The filename should come last; it should accept multiple filenames (for
wildcard support); it should loop over the filenames (always using $1,
and using `shift', would do the trick, or a for loop); the example won't
work as given because you've got the sed command (the s/) in the script
*and* in both the arguments...

(I could go on...)

> for file in foo*; do ./harrysed sedscript.sh 's\/hte\/the\/'
> 's\/hte\/the\/g'; done

FROM=$1
TO=$2
shift 2;
for file in $@; do mv -f $file ${file}~ && \
    sed s/`echo $FROM | sed 's,/,\/,g'`/`echo $TO | sed 's,/,\/,g'/g > $file
done

should do it.

Bugs: not robust against aliases for `mv' to `mv -i'; not robust against
`from' and `to' argument starting with minus signs (easily implementable,
change `echo $foo' to `echo x$foo | cut -c2-' but it would uglify the
script even more).

But it handles FROM and TO arguments containing slashes (and everything
else, because the regexp-replacement code has a static command so there
is no danger of anything colliding with its separator character), and it
handles multiple filenames.

> for file in `find . -print | xargs file | grep text | sed 's/:.*//'`; do
> ...;done

Nice one :) but maybe you *want* to do textual replacement on those core
files ;)

> The correct technology for the task in hand is to use regular
> expressions. (These are the s/...// things)

Well, they're the bit that the ... is replaced by.

> Regexps are available in perl, sed, vi, emacs, python and even Java.
> I think a variant is available in awk.

awk's pattern-matching is fundamentally dependent upon regexps :) it
also has `match' which takes regexps. `Regexp constants' are even a
special kind of string constant (delimited by / instead of '
characters).

-- 
`The situation is completely under control. All of them were killed.'
     --- Alim Razim, for the Northern Alliance, demonstrating fine
         command of traditional Afghan prisoner control techniques.

-- 
Gllug mailing list  -  Gllug at linux.co.uk
http://list.ftech.net/mailman/listinfo/gllug




More information about the GLLUG mailing list