[comp.unix.questions] ed & redirected input

funk@osiris.cso.uiuc.edu (05/15/89)

If I have a script segment of the following form ....

site=<somevalue>
cmty=<someothervalue>

for i in file1 file2 file3
do
ed $i <<honker
1,\$ s/pat1/$site/g
1,\$ s/pat2/$cmty/g
w
q
honker
done

It works like a champ  EXCEPT if one of the files (say file2) does NOT contain
an occurrence of pat1.  Then ed proceeds to ignore everything else except the
q, (and it complains about not having seen a "w"), with the effect that the
file is NOT updated, even though it should have worked for the occurrences
of pat2.  All other files are correctly updated, as they contain occurrences of
both pat1 and pat2.  If I do it by hand, ed of course complains about the
no match, but still processes any subsequent commands.

I finally gave up and resorted to using sed into a temp file and moving the
temp file back to the original file.  But it still leaves me wondering
          HOWCUM????  

I am working on a UNISYS 5000/80 running SYSTEM V, Rel 2.

-------------------------------------------------------------------------------
|        Bruce Funk                         INTERNET: funk@osiris.cso.uiuc.edu |
|ACSEH, 21st TAACOM          __________________________________________________|
|Kaiserslautern, W. Germany  | Any resemblance between me and reality          |
|(guesting on osiris)        | is strictly coincidental                        |
-------------------------------------------------------------------------------

chris@mimsy.UUCP (Chris Torek) (05/16/89)

In article <9700003@osiris.cso.uiuc.edu> funk@osiris.cso.uiuc.edu writes:
[the important lines ...]
>ed $i <<honker
>1,\$ s/pat1/$site/g
>1,\$ s/pat2/$cmty/g
>w
>q
>honker

>It works like a champ EXCEPT if one of the files (say file2) does NOT contain
>an occurrence of pat1. ...
>          HOWCUM????  

On an error (such as `no matches') ed discards pending input, making
EOF the next thing it sees.  (You could remove the `q' command and
you would see the same behaviour.)

There is a simple work-around:

	ed - $i << end
	g/pat1/s//$site/g
	g/pat2/s//$cmty/g
	w
	end

(the `-' suppresses the two number-of-characters reports).
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

guy@auspex.auspex.com (Guy Harris) (05/17/89)

>It works like a champ  EXCEPT if one of the files (say file2) does NOT contain
>an occurrence of pat1.  Then ed proceeds to ignore everything else except the
>q,

Yup.  That's deliberate.  A command of the form "1,$s/pat1/pat2/g" fails
if it doesn't find at least one instance of "pat1"; if a command fails,
"ed" assumes that the script isn't finding what it expects to find, and
therefore blows the rest of the script off, under the assumption that
you may not get the results you expect from the script....

>I finally gave up and resorted to using sed into a temp file and moving the
>temp file back to the original file.  But it still leaves me wondering
>          HOWCUM????  

See above.

If you want a "substitute" command of that sort that *doesn't* fail if
it doesn't find any instances of the pattern, try

	g/pat1/s//pat2/g

rather than

	1,$s/pat1/pat2/g

itkin@mrspoc.UUCP (Steven M. List) (05/17/89)

In article <9700003@osiris.cso.uiuc.edu> funk@osiris.cso.uiuc.edu writes:
> ed $i <<honker
> 1,\$ s/pat1/$site/g
> 1,\$ s/pat2/$cmty/g
> w
> q
> 
> It works like a champ  EXCEPT if one of the files (say file2) does NOT contain
> an occurrence of pat1.  Then ed proceeds to ignore everything else except the
> q, (and it complains about not having seen a "w"), with the effect that the
> file is NOT updated, even though it should have worked for the occurrences
> of pat2.  All other files are correctly updated, as they contain occurrences
> of both pat1 and pat2.  If I do it by hand, ed of course complains about the
> no match, but still processes any subsequent commands.
> 
I'm not sure if this is EXACTLY your problem, but I've run into this before.
The problem is that ED doesn't like "1,$s/x/y/" if there are no "x" strings
in the file.  The cleaner way to do this, when you want to perform these
operations across the whole file is to use the global command:

ed $i <<honker
1,\$ g/pat1/s//$site/g
1,\$ g/pat2/s//$cmty/g
w
q
honker

Since the global command causes (1) all lines that satisfy the search
criteria to be marked and then (2) all marked lines to be operated on,
this doesn't fail when there ARE no marked lines.
-- 
:  Steven List @ Transact Software, Inc. :^>~
:  Chairman, Unify User Group of Northern California
:  {apple,coherent,limbo,mips,pyramid,ubvax}!mrspoc!itkin
:  Voice: (415) 961-6112