Path: utzoo!attcan!uunet!pcserver2!ddsw1!dattier From: dattier@ddsw1.MCS.COM (David W. Tamkin) Newsgroups: comp.editors Subject: Re: sed output Message-ID: <1991Feb27.172236.7202@ddsw1.MCS.COM> Date: 27 Feb 91 17:22:36 GMT References: <1991Feb20.234921.5738@ddsw1.MCS.COM> <1991Feb25.184548.14778@chinet.chi.il.us> Organization: Contributor Account at ddsw1, Wheeling, Illinois Lines: 102 les@chinet.chi.il.us (Leslie Mikesell) wrote in <1991Feb25.184548.14778@chinet.chi.il.us>: | In article <1991Feb20.234921.5738@ddsw1.MCS.COM> dattier@ddsw1.MCS.COM | (David W. Tamkin) writes: | >Hmmm...this is knotty to explain... I'm running sed in a for loop (in sh) | >on several input files. Let's call them A, B, C, D, and E. The sed script | >should send output to three places. If I made a separate output file for | >each one, I'd finish with fifteen output files: Ax, Ay, Az, Bx, etc., through | >Ez. What I really want are a single x file, y file, and z file. | >When a sed script begins, sed scans for w operators and creates all target | >files needed. If files by those names already exist, tough; the old contents | >are clobbered. So if I use "w x" and "w y" in the script and redirect sed's | >stdout >>z, only z will have the proper contents; x and y will have only the | >extractions from input file E. | If the input files all exist at once, let sed iterate over the list of | filenames instead of the shell. Multiple w's within a script will append. Les, what I'm guessing you mean here is that I should use sed -f scriptfile infile1 infile2 ... > outfile instead of for i in infile1 infile2 ... ; do sed -f scriptfile $i ; done >> outfile I had two problems with that approach: first, I didn't know how to make the sed script realize that it was starting on a new input file and thus should operate on the last line of each input file in a particular way, given that it was last, and operate on the first line of every input file as I instructed it for the first line of the entire input. Ideally, yes, that would have saved forking sed again for each file of the input, but sed has no way to address "last line before you start taking input from somewhere else" nor "first line of a new input source." It acts as if you had catted them together first. Second, one of the files contains text before the sed even starts. I could use it as >>stdout (file z in my explanation) except for one thing: it's the one that receives output of a single w per pass. The other file (there really are only two, not three; I was illustrating before) gets the output of all the p commands plus one P command. Yes, I could interchange the p's with the w, but how do I make a w out of the P without clobbering the hold space? Plus, at the time I first asked, the script had print-at-end-of-cycle as the default -- no, that's an easy one: just change all the b's to bz, stick #n at the top or -n on the command line, and end the script with d :z w filename which I didn't do anyway, because the script in its final form was run with sed -n and the b's became p's (or sometimes p ; d to avoid dropping down into commands that would mess up the hold space). Actually, it's not all that easy, because I had a lot of n's too. Without -n in effect, interchanging stdout and wfile would have meant changing a simple n to w filename N s/.*\n// to avoid getting shot back to the top of the sed script, as D would do. Forking sed separately for each input file means clobbering whichever output file gets the honor of being the w destination. I suppose that I could just have come up with a bunch of wfiles and concatenated the lot together afterwards. As it turns out I did find a way to spot the first line of each input file and apply the same commands to it and the lines that followed as to the corresponding lines at the beginning of the first input file, and thus run sed in only one pass. The single line per input file that needed to be appended to the existing file I w'ed to a fifo to be catted >>the existing file. System V doesn't let sed clobber fifos, fortunately. | Ahh, but with perl, you typically only have to learn one arcane set of | commands and syntax instead of the several you need to know to write | useful shell scripts. If you really care about reducing the number of | forks (at the expense of some start-up time), perl is the way to go. Yes, I knew that. It probably doesn't take all that many forks of smaller programs before there's more overhead than for one fork of perl. Are you volunteering to teach me, Les? You know where I live. | Probably not, but there is still a simple alternative. Just do the | editting portion of the script with ex. You probably already know | the appropriate syntax and it supports the w >>file command to explicitly | append. As an added benifit you also get the ability to specify an | address an arbitrary number of lines above a pattern match and some | other things that are impossible in sed (at the expense of making a | temporary copy of the file). That's not so simple for this application. There are a number of things I'm doing in the sed script that would be really bearish in ex; the first that comes to mind is how to resume the editing from the beginning when the next input file is ready. (Surely I shouldn't have to change the script to have N copies of itself when the input contains N files.) That brings us back to having the shell, not the editor, do the cycling and thus forking the editor again and again. The second is that one thing I'm doing involves handling the case of a pattern that doesn't show up by h'ing it when it arrives and then, after its last chance to appear, g'ing and checking for its presence. In ex I'd have to do a pattern search for it, and if it isn't there, the ex script will break; moreover, if I am trying to ex the entire input in one fork, a pattern search while I'm working on a portion that is missing the pattern will land on its occurrence in another portion, and then KABOOM. This is the sort of thing that awk and perl are for. I'm trying to cut down a sapling with a carving knife. It's better than a butterknife, and I don't need a chainsaw, but a regular saw would be very nice to have use of. David Tamkin Box 7002 Des Plaines IL 60018-7002 708 518 6769 312 693 0591 dattier@ddsw1.mcs.com MCI Mail: 426-1818 CIS: 73720,1570 GEnie: D.W.TAMKIN