[comp.unix.questions] ed problem

dinah@krebs.bcm.tmc.edu (08/31/89)

I am having problem with the following script. I want to edit some
c files that begin with AA_. I and to change all combinations of AA_
to the corresponding BB_. I know there is a more efficient way to do
it but the following should work. The problem seems to be that the edit
works successfully, but the file does not get written back with the changes.
It worked for a the first few times (I invoked the script repeatedly until
all occurences were changed. I know it's crude. :-)) Any way the script
prints the changes correctly, but they just don't get written back! Any 
ideas on what is going wrong?

#! /bin/sh
for files in `grep -i AA_ *.c | awk -F: '{ print $1 }' | sort -u`
	do
	ed $files << EOF
/aa_/
s/aa_/bb_/p
/AA_/
s/AA_/BB_/p
/Aa_/
s/Aa_/Bb_/p
w $files
q
EOF
	done
Dinah Anderson					 internet: dinah@bcm.tmc.edu 
Baylor College of Medicine	           uucp: {rutgers,mailrus}!bcm!dinah

pme@io.UUCP (Paul English x3168) (08/31/89)

dinah@krebs.bcm.tmc.edu writes:

>I am having problem with the following script. I want to edit some
>c files that begin with AA_. I and to change all combinations of AA_
>to the corresponding BB_. [...]

>#! /bin/sh
>for files in `grep -i AA_ *.c | awk -F: '{ print $1 }' | sort -u`
>	do
>	ed $files << EOF
>/aa_/
>s/aa_/bb_/p
>/AA_/
>s/AA_/BB_/p
>/Aa_/
>s/Aa_/Bb_/p
>w $files
>q
>EOF

It is not necessary to use grep first to filter out files which
contain the pattern, and in fact it makes extra work. Let ed look for
the pattern. If it doesn't find it, that is ok.

I would recommend something like the following, a general purpose
``edit files and globally replace pattern'' shell script. (I call this
script `edg'.)

    :

    if [ $# -lt 3 ]; then
	echo "usage: $0 OLDSTR NEWSTR FILES"
	exit 1
    fi

    old=$1; new=$2; shift 2

    for file
    do
	echo $file
	ed - $file << +
	    1,\$s'$old'$new'g
	    w
    +
    done

Thus, you would invoke it like this:
    % edg AA_ BB_ *.c
When it edits a file without AA_, ed will complain with a `?', but you
can ignore it.    
-- 
Paul M. English
  Interleaf, Cambridge: pme@ileaf.com, !{sun!sunne,mit-eddie}!ileaf!pme
  UMass/Boston: pme@umb.edu, !harvard!umb!pme

rbj@dsys.ncsl.nist.gov (Root Boy Jim) (09/01/89)

? From: dinah@krebs.bcm.tmc.edu

See my other posting on this.

? #! /bin/sh
? for files in `grep -i AA_ *.c | awk -F: '{ print $1 }' | sort -u`

There is no need to use awk. "Grep -l pattern files" prints the list
of files in which pattern appears, and quits searching each file
when the first occurance of pattern is found.

? Dinah Anderson				 internet: dinah@bcm.tmc.edu 
? Baylor College of Medicine	           uucp: {rutgers,mailrus}!bcm!dinah

	Root Boy Jim and
	the GNU Bohemians

rbj@dsys.ncsl.nist.gov (Root Boy Jim) (09/01/89)

? From: Paul English x3168 <pme@io.uucp>

? dinah@krebs.bcm.tmc.edu writes:

? >I am having problem with the following script. I want to edit some
? >c files that begin with AA_. I and to change all combinations of AA_
? >to the corresponding BB_. [...]

? It is not necessary to use grep first to filter out files which
? contain the pattern, and in fact it makes extra work. Let ed look for
? the pattern. If it doesn't find it, that is ok.

Good point. No point in scanning text twice.

? I would recommend something like the following, a general purpose
? ``edit files and globally replace pattern'' shell script. (I call this
? script `edg'.)

?     :
?
?     if [ $# -lt 3 ]; then
? 	echo "usage: $0 OLDSTR NEWSTR FILES"
? 	exit 1
?     fi
?
?     old=$1; new=$2; shift 2
?
?     for file
?     do
? 	echo $file
? 	ed - $file << +
? 	    1,\$s'$old'$new'g
? 	    w
?     +
?     done

? Thus, you would invoke it like this:
?     % edg AA_ BB_ *.c
? When it edits a file without AA_, ed will complain with a `?', but you
? can ignore it.    

Except that you don't want to use ed, you want to use sed. Replace the
guts between `do' and `done' with the following

	echo $file
	sed "s'$1'$2'g" $file > $$
	mv $$ $file

There are several problems with this. First, if the pattern contains
single quotes, it will fail. Second, if it contains regular expression
characters, they must be quoted by the appropraite number of
backslashes, an interesting exercise. Third, I use $$, the pid name of
the shell as a temp file. If it previously existed, it willl be wiped
out. Since this is not my problem, I decline to solve it further.

? Paul M. English
?   Interleaf, Cambridge: pme@ileaf.com, !{sun!sunne,mit-eddie}!ileaf!pme
?   UMass/Boston: pme@umb.edu, !harvard!umb!pme

	Root Boy Jim and
	the GNU Bohemians