Bash: Extract Range with Regular Expressioin (maybe sed?)
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.
sed -n "/SUMMARY/,/END OF SUMMARY/p" fileName
If Perl
is fine you can use:
perl -e 'print $1 if(`cat FILE_NAME`=~/SUMMARY:\n(.*?)END OF SUMMARY/s);'
If you don't want to print the marker lines:
sed '1,/SUMMARY/d;/END OF SUMMARY/,$d' filename
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
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.
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>
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/
精彩评论