tags:

views:

141

answers:

7

I have a file that is similar to this:

<many lines of stuff>
SUMMARY:
<some lines of stuff>
END OF SUMMARY

I want to extract just the stuff between SUMMARY and END OF SUMMARY. I suspect I can do this with sed but I am not sure how. I know I can modify the stuff in between with this:

sed "/SUMMARY/,/END OF SUMMARY/ s/replace/with/" fileName

(But not sure how to just extract that stuff).

I am Bash on Solaris.

+1  A: 

If Perl is fine you can use:

perl -e 'print $1 if(`cat FILE_NAME`=~/SUMMARY:\n(.*?)END OF SUMMARY/s);'
codaddict
Yeah, I like perl too but my team are more seddy people.
sixtyfootersdude
I like Perl too, but this one really sounds more like a job for sed.
JB
+5  A: 
sed -n "/SUMMARY/,/END OF SUMMARY/p" fileName
sixtyfootersdude
This also matches: ....SUMMARY....END OF SUMMARYAdding '^' to require matching the NULL string at the beginning of pattern space:sed -n "/^SUMMARY/,/^END OF SUMMARY/p"
Jürgen Hötzel
If you do that it is probably a good Idea to add an end an end of line marker as well. Ie: `sed -n "/^SUMMARY$/,/^END OF SUMMARY$/p"`
sixtyfootersdude
A: 

You can do this with awk:

$ echo 'many
lines
of
stuff
SUMMARY:
this is the summary
over two lines
END OF SUMMARY' | awk '
    BEGIN              {e=0}
    /^END OF SUMMARY$/ {e=0}
                       {if (e==1) {print}}
    /^SUMMARY:$/       {e=1}'

which outputs:

this is the summary
over two lines

Not all implementations of awk will require the BEGIN clause but I always like to include explicit initialisation.

It works by using an echo flag (e) to decide whether you're in the summary section or not.

paxdiablo
+1  A: 

If you don't want to print the marker lines:

sed '1,/SUMMARY/d;/END OF SUMMARY/,$d' filename
Dennis Williamson
A: 

On Solaris , use nawk

#!/bin/bash
nawk '
/SUMMARY/{
 gsub(".*SUMMARY:","");
 f=1
}
/END OF SUMMARY/{f=0;
 gsub("END OF SUMMARY.*","")
}f' file

output

$ cat file
1 2 3 <many lines of stuff>
4 5 6 SUMMARY: 7 8 9
<some lines of stuff>
END OF SUMMARY blah
blah

$ ./shell.sh
 7 8 9
<some lines of stuff>
ghostdog74
+1  A: 

This should work using (FreeBSD) sed as well:

sed -E -n -e '/^SUMMARY:/,/^END OF SUMMARY/{ /^SUMMARY:/d; /^END OF SUMMARY/d; p;}' file.txt 
sedit
What is the advantage of that over `sed -n "/^SUMMARY$/,/^END OF SUMMARY$/p" fileName` ?
sixtyfootersdude
A: 

Here's yet another sed version just doing a multi-line print & quit (which may be suitable for extracting a range of lines from a large file):

sed -E -n -e '/^SUMMARY:$/{n;h;};/^END OF SUMMARY$/!H;/^END OF SUMMARY$/{g;p;q;}' fileName | sed 1d 

For a multi-line sed script pretty well explained see:

http://ilfilosofo.com/blog/2008/04/26/sed-multi-line-search-and-replace/

tallyo
Hum. Had a look at that reference but I still think it that is better to do replaces using a range rather than buffers. Interested to hear if/why you think buffers are better.
sixtyfootersdude