[net.unix] Putting in newlines using sed

michaelm@bcsaic.UUCP (michael b maxwell) (11/15/85)

This is on BSD 4.2...
I have a process putting out lines that look something like this:
	fjlkjf foo (a b c) jflkjf (jfkj)  foo (x y a) fjjfj
I want to break up the line so that each "foo" followed by its
parenthesized list of arguments appears on a separate line.  I don't
care what happens to the other "words;" they are eliminated in
later processing.

My first thought was to use sed to do the ff:
	s/foo/^Mfoo/g
-where "^M" is what I get by typing a ^V followed by a carriage return.
What sed does with this is to substitute a ^M, i.e. a carriage return--
but no line feed.  On the screen, the result is that you only see
the last "foo" plus whatever follows it; all the rest are overprinted.
And naturally this isn't what the following processes in the pipeline
expect...  So then I tried using to do the following:
	s/foo/^Jfoo/g
Well, I couldn't get the ^J in there!  I couldn't hide it from the shell
with ^V, \, ', " or anything else I could think of (I even tried using
vi to put it into a file of sed commands).  As far as I can tell, there's no 
way of writing the s/... line above with a *real* linefeed in place of the ^
and J.

Next, I tried ex.  Now ex will put a linefeed in, rather than a carriage
return, given the first s/... line above;  but as far as I can see, ex 
can't edit a pipeline-- it only edits files (which is why sed exists, I 
imagine!).  (You can get ex to send its output to a pipe, by doing %p.)

What I finally settled on was to use sed to insert ^Ms, then tr to
translate the ^Ms to ^Js (linefeeds).  Can you say "kludge"?  It works,
but at the cost of quite a bit of overhead--the next step in the
processing uses sed again, so the pipeline looks like:
	... \ 
	| sed (insert ^Ms) \
	| tr (convert ^Ms to ^Js) \
	| sed (command A; command B; command C...) \
	| ...
If I could eliminate the tr step, I could make "insert linefeed"
be the first command that sed does, thus eliminating two processes.

So far as I can say, there is no way of using tr to insert the ^Js in
the first place.  And no, we don't have rpl.  If I ever have time to sit
down and learn emacs, I'll probably find that I can use that, though I'm
not sure it can edit a stream rather than a file.  (Comments?)

Any ideas?
-- 
Mike Maxwell
Boeing Artificial Intelligence Center
	...uw-beaver!uw-june!bcsaic!michaelm

rt@cpsc53.UUCP (Ron Thompson) (11/18/85)

> I have a process putting out lines that look something like this:
> 	fjlkjf foo (a b c) jflkjf (jfkj)  foo (x y a) fjjfj
> I want to break up the line so that each "foo" followed by its
> parenthesized list of arguments appears on a separate line.  I don't
> care what happens to the other "words;" they are eliminated in
> later processing.
> 
> As far as I can tell, there's no 
> way of writing the s/... line above with a *real* linefeed in place of the ^
> and J.
> 

With Sys V just type the following from the shell:

sed 's/foo/\
> foo/g' filename

The backslash escapes your newline producing a series of lines
all that begin with foo.


-- 
  Ron Thompson		AT&T Information Systems	Customer Programming  
  ..akgua!cpsc53!rt 	Atlanta, Georgia		Services Center	      
  (404) 982-4524        (Opinions expressed are mine alone.)

jerryp@tektools.UUCP (Jerry Peek) (11/18/85)

In article <376@bcsaic.UUCP> michaelm@bcsaic.UUCP (michael b maxwell) writes:
> This is on BSD 4.2...
> I have a process putting out lines that look something like this:
> 	fjlkjf foo (a b c) jflkjf (jfkj)  foo (x y a) fjjfj
> I want to break up the line so that each "foo" followed by its
> parenthesized list of arguments appears on a separate line.  I don't
> care what happens to the other "words;" they are eliminated in
> later processing.

In Bourne shell:

	sed 's/foo/\
	foo/g'

In C-shell, you'll need a second backslash:

	sed 's/foo/\\
	foo/g'

--Jerry Peek, UNIX Training Instructor, Tektronix, Inc.
US Mail:    MS 74-222, P.O. Box 500, Beaverton, OR 97077
uucp:       {allegra,decvax,hplabs,ihnp4,ucbvax}!tektronix!tektools!jerryp
CS,ARPAnet: jerryp%tektools@tektronix.csnet
Phone:      503/627-1603

preece@ccvaxa.UUCP (11/18/85)

> This is on BSD 4.2...  I have a process putting out lines that look
> something like this:
>	fjlkjf foo (a b c) jflkjf (jfkj)  foo (x y a) fjjfj
> I want to break up the line so that each "foo" followed by its
> parenthesized list of arguments appears on a separate line.  I don't
> care what happens to the other "words;" they are eliminated in later
> processing.  /* Written 12:29 pm  Nov 15, 1985 by michaelm@bcsaic.UUCP
> in ccvaxa:net.unix */
----------
You're just not quoting enough.  The cshell is grabbing your
quote character.  The command 
	sed 's/foo/\\^Jfoo/g' filename
where '^J' is the actual control-J character, and filename is
the name of your file (piping in will work fine).

You could also put the command in a file, with just one backslash.

-- 
scott preece
gould/csd - urbana
ihnp4!uiucdcs!ccvaxa!preece

sarwate@uicsl.UUCP (11/18/85)

Using the sed command

s/ foo/\
foo/g

seems to work on the 4.2BSD version of sed.  Note that the newline character
as given by the RETURN key follows the \ on the first line.

jpn@teddy.UUCP (11/19/85)

>I have a process putting out lines that look something like this:
>	fjlkjf foo (a b c) jflkjf (jfkj)  foo (x y a) fjjfj
>I want to break up the line so that each "foo" followed by its
>parenthesized list of arguments appears on a separate line.
>
>...  So then I tried using to do the following:
>	s/foo/^Jfoo/g

I had no problem, in csh:

% sed 's/foo/\\
foo/g'

in sh:

$ sed 's/foo/\
> foo/g'


(don't type the prompts)  The trick is that sed will accept a newline in
one of it's patterns if it is escaped with a backslash.  The csh example
needs a second backslash to tell the shell that the command line is not
complete.

vsh@pixdoc.UUCP (Steve Harris) (11/20/85)

Some time ago I tried to do just what you describe.
I eventually gave up, but was working on the idea of:

	save line in hold buffer
loop:	
	yank hold buffer
	delete everything after first "foo ([^)]*)", and print
	yank hold buffer
	delete first "foo ([^)]*)"
	save result in hold buffer
	test somehow whether or not you're done
	if not done, goto loop

I think it can be done, I just never saw it through.

good luck, please post your code if you succeed
(it should be pretty ugly!! :-)

-- 

Steve Harris            |  {allegra|ihnp4|cbosgd|ima|genrad|amd|harvard}\
Pixel Systems Inc.      |               !wjh12!pixel!pixdoc!vsh
300 Wildwood Street     |
Woburn, MA  01801       |  617-933-7735 x2314

vsh@pixdoc.UUCP (Steve Harris) (11/20/85)

re: my previous suggestion -- never mind!

I just saw Ron Thompson's posting; and it works!
(now why didn't I think of that? :-)

-- 

Steve Harris            |  {allegra|ihnp4|cbosgd|ima|genrad|amd|harvard}\
Pixel Systems Inc.      |               !wjh12!pixel!pixdoc!vsh
300 Wildwood Street     |
Woburn, MA  01801       |  617-933-7735 x2314

chris@umcp-cs.UUCP (Chris Torek) (11/20/85)

Feeding `sed' newlines is easy; the real trick is getting the C shell
to hand it the right stuff.

The sed documentation says that in order to insert newlines in
substitute commands, you should quote them with backslash:

	sed -e 's/foo/b\
	a\
	r/'

Indeed, this works quite well in the Bourne shell, which does what
I consider the `proper' thing with this input.  The C shell, however,
thinks it is smarter than you are, and *removes* the trailing
backslashes!  So instead you must type

	sed -e 's/foo/b\\
	a\\
	r/'

Probably the best solution is to place your sed commands in a
separate file; then which shell is used no longer matters.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@mimsy.umd.edu

michaelm@bcsaic.UUCP (michael b maxwell) (11/21/85)

Thanks to all those who pointed out that I needed *two* backslashes in
C-shell to hide the linefeed (but only one in Bourne shell).  (I should 
have mentioned that I was using C-shell in the original posting; I didn't 
realize it would make a difference to this problem!)

Incidently, I can hide the linefeed in C-shell with two backslashes so
that the ^J shows up on the same line; but I can't do that in vi...  There
the ^J shows up as a linefeed. Not that it makes much difference, it's
just not as "pretty."  (i.e. messes up the clarity of the program).
-- 
Mike Maxwell
Boeing Artificial Intelligence Center
	...uw-beaver!uw-june!bcsaic!michaelm