[comp.unix.wizards] A little help with SED please - cla

rjd@occrsh.ATT.COM (04/21/88)

:I need an sed line (or some gory pipeline) to extract the data between
                     ^^^^^^^^^^^^^^^^^^^^^^
:BEGIN and END.
:
:I should have added the following:
:
:	>I have a text file of this form:
:	    [... junk ...]
:	>   BEGIN
:	>     1
:	>     2
:	>     3
:	>   END
:	    [... junk ...]
:	>   BEGIN
:	>     4
:	>     5
:	>     6
:	>   END
:	    [... junk ...]

   Is "awk" gory enough??? :-)   Here's an awk script:

cat <text file> | awk -f script

where 'script' is a file containing this:
--------- cut here ---------
BEGIN {
	prnt=0
	bgn=0
}

/BEGIN/ && $0 == "BEGIN" {prnt=1;bgn=1}
/END/ && $0 == "END" {prnt=0}

NF > 0 {
if( prnt == 1 && bgn != 1)
	print $0
bgn=0
}
--------- cut here ---------

Randy

jlw@lznv.ATT.COM (j.l.wood) (04/22/88)

In article <142700030@occrsh.ATT.COM>, rjd@occrsh.ATT.COM writes:
> 
> :I need an sed line (or some gory pipeline) to extract the data between
>                      ^^^^^^^^^^^^^^^^^^^^^^
> :BEGIN and END.
> :
> :I should have added the following:
> :
> :	>I have a text file of this form:
> :	    [... junk ...]
> :	>   BEGIN
> :	>     1
> :	>     2
> :	>     3
> :	>   END
> :	    [... junk ...]
> :	>   BEGIN
> :	>     4
> :	>     5
> :	>     6
> :	>   END
> :	    [... junk ...]
> 
>    Is "awk" gory enough??? :-)   Here's an awk script:
> 
> cat <text file> | awk -f script
> 
> where 'script' is a file containing this:

Some Stuff Deleted:

The following awk command line seems to do what you want:

	cat <text file> |\
	awk '/BEGIN/,/END/ { if( $0 != "BEGIN" && $0 != "END" ) print }'



Joe Wood
lznv!jlw

I
n
e
w
s

f
o
d
d
e
r

m
o
r
e

f
o
d
d
e
r

lew@gsg.UUCP (Paul Lew) (04/22/88)

 > I need an sed line (or some gory pipeline) to extract the data between
 >                      ^^^^^^^^^^^^^^^^^^^^^^
 > BEGIN and END.
 > 
 > I should have added the following:
 > 
 > 	>I have a text file of this form:
 > 	    [... junk ...]
 > 	>   BEGIN
 > 	>     1
 > 	>     2
 > 	>     3
 > 	>   END
 > 	    [... junk ...]
 > 	>   BEGIN
 > 	>     4
 > 	>     5
 > 	>     6
 > 	>   END
 > 	    [... junk ...]
 > 

It is very simple to do if the lines contain BEGIN or END should be
included:

   (1) awk '/BEGIN/,/END/' filename		

It is a bit tricker if you want to exclude BEGIN, END lines:

   (1) awk '/END/ {p=0} p==1 {print} /BEGIN/ {p=1}' filename	or
   (2) echo '/BEGIN/+1,/END/-1p' | ex - filename		or
   (3) sed -n '/BEGIN/,/END/{/BEGIN/d;/END/d;p;}' filename

I dont like the awk script because I have to THINK about the logic, the
2nd command is easier to use but it only handle the 1st occurrence and
slower. The sed script is tricky to remember too, it should be the fastest
among the 3 choices listed above.
-- 
Paul Lew			{oliveb,harvard,decvax}!gsg!lew	(UUCP)
General Systems Group, 5 Manor Parkway, Salem, NH 03079	(603) 893-1000

les@chinet.UUCP (Leslie Mikesell) (04/22/88)

>
>:I need an sed line (or some gory pipeline) to extract the data between
>                     ^^^^^^^^^^^^^^^^^^^^^^
>:BEGIN and END.

How about:
sed -n -e '/BEGIN/,/END/p' |sed -e '/BEGIN/d' -e '/END/d'

perhaps with ^BEGIN$ if you want to force matches to full lines or
changing the second sed to s/BEGIN// if you don't.

  Les Mikesell

wallen@sdics.ucsd.EDU (Mark Wallen) (04/22/88)

In article <146@gsg.UUCP> lew@gsg.UUCP (Paul Lew) writes:
>
> > I need an sed line (or some gory pipeline) to extract the data between
> >                      ^^^^^^^^^^^^^^^^^^^^^^
> > BEGIN and END.
> > 
[Elided--mrw]
>It is very simple to do if the lines contain BEGIN or END should be
>included:
>
>   (1) awk '/BEGIN/,/END/' filename		
>
>It is a bit tricker if you want to exclude BEGIN, END lines:
>
>   (1) awk '/END/ {p=0} p==1 {print} /BEGIN/ {p=1}' filename	or
>   (2) echo '/BEGIN/+1,/END/-1p' | ex - filename		or
>   (3) sed -n '/BEGIN/,/END/{/BEGIN/d;/END/d;p;}' filename
[Elided--mrw]

Wither have the 'ed' hackers of yore gone?  I suppose they're
all 'ex' hackers now :-).  If you change (2) to
echo 'g/BEGIN/.+1,/END/-1p' | ex - filename
(or ed instead of ex), you'll get all data between BEGIN,END
pairs EXCEPT when there is no data.  I.e.,
	BEGIN
	END

Both editors abort on this case (ed with the wonderfully
informative "?" message; thank zeus that some things haven't
changed :-)

Mark R. Wallen
UC San Diego

mwallen@ucsd.edu

dkc@hotlr.ATT (Dave Cornutt) (04/23/88)

In article <142700030@occrsh.ATT.COM> rjd@occrsh.ATT.COM writes:
 > 
 > :I need an sed line (or some gory pipeline) to extract the data between
 > :BEGIN and END.
 > 
 >    Is "awk" gory enough??? :-)   Here's an awk script:
 > ...

Nah, too much trouble.  Try this:

awk -e '/BEGIN/,/END/' foo
-- 
Dave Cornutt, AT&T Bell Labs (rm 4A406,x1088), Holmdel, NJ
UUCP:{ihnp4,allegra,cbosgd}!hotly!dkc
"The opinions expressed herein are not necessarily my employer's, not
necessarily mine, and probably not necessary"

chris@mimsy.UUCP (Chris Torek) (04/23/88)

In article <142700030@occrsh.ATT.COM> rjd@occrsh.ATT.COM writes:
[bits, words, and paragraphs deleted]
-BEGIN {
-	prnt=0
-	bgn=0
-}
-
-/BEGIN/ && $0 == "BEGIN" {prnt=1;bgn=1}
-/END/ && $0 == "END" {prnt=0}
-
-NF > 0 {
-if( prnt == 1 && bgn != 1)
-	print $0
-bgn=0
-}

The variable `bgn' can be eliminated by using the `next' construct:

	/^BEGIN$/ { prt = 1; next }	# tweak R.E. as appropriate
	/^END$/ { prt = 0 }
	NF > 0 { if (prt) print }

Voila!, three lines.  This does depend on uninitialised variables
being numerically zero, which is true in awk, but perhaps considered
bad style.  If so, add a fourth line:

	BEGIN { prt = 0 }
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris