• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 730
  • Last Modified:

Want to print the last N sections of text between two delimiters using AWK or SED

I have a text file from which I want to extract the last N number of ranges of delimited text.  The number of delimited ranges in this file will always be changing.

Following is an example of the input file.  Note that the ranges I want to extract are delimited by "/== START OF CHECK ==/" and "/== END OF CHECK ==/"   There can be any number of lines with any number of characters per line between delimiters.  

Here's the input file:
/== START OF CHECK ==/
Thu Jun  3 13:28:01 EDT 2010
...
... random number of lines of information
...
/== END OF CHECK ==/

/== START OF CHECK ==/
Thu Jun  3 13:30:01 EDT 2010
...
... random number of lines of information
...
...
/== END OF CHECK ==/

/== START OF CHECK ==/
Fri Mar 11 04:15:01 EST 2011
...
... random number of lines of information
...
/== END OF CHECK ==/

/== START OF CHECK ==/
Fri Mar 11 04:30:01 EST 2011
...
... random number of lines of information
...
/== END OF CHECK ==/

/== START OF CHECK ==/
Fri Mar 11 04:45:01 EST 2011
...
... random number of lines of information
...
/== END OF CHECK ==/

Using the beginning and ending delimiters, how can I use AWK or SED to extract the last N ranges of text?  

Using the example file above, if I wanted the last 3 ranges, I would get:
/== START OF CHECK ==/
Fri Mar 11 04:15:01 EST 2011
...
... random number of lines of information
...
/== END OF CHECK ==/

/== START OF CHECK ==/
Fri Mar 11 04:30:01 EST 2011
...
... random number of lines of information
...
/== END OF CHECK ==/

/== START OF CHECK ==/
Fri Mar 11 04:45:01 EST 2011
...
... random number of lines of information
...
/== END OF CHECK ==/
0
rdavis777
Asked:
rdavis777
  • 2
1 Solution
 
woolmilkporcCommented:
Not very elegant (rather "quick and dirty"):

#!/bin/sh

IN=/path/to/inputfile
NUMSEC=number_of_sections
 
SECB="START OF CHECK"
SECE="END OF CHECK"
START=$(($(grep -c "$SECB" $IN)-$NUMSEC))

sed -n "/$SECB/,/$SECE/p" $IN | \
 awk -v S=$START -v B="$SECB" -v E="$SECE" \
  '{if(n>=S) {if ($0~B) P="Y"; if(P=="Y") print}; if ($0~B) n+=1}'

exit

wmp
0
 
point_pleasantCommented:
here is a perl script to do it

USAGE perl progname < text_file > output_file

$inblock = 0;
while (<>) {
        if ((( $_ =~ /^.* START /) || ($inblock == 1)) && ($_ !~ /^.* END/)) {
                print $_;
                $inblock = 1;
        } elsif ($_ =~ /^.* END/) {
                print $_;
                $inblock = 0;
        }
}
0
 
point_pleasantCommented:
oops didn't read the whole question, here is complete for the last nsection

usage perl paroname.pl input_file number_sections

$inblock = 0;
open (INFILE, "<$ARGV[0]");
open (TMPFILE, ">/tmp/tmpfile");
@file = reverse <INFILE>;
$numsecs=$ARGV[1];
$sec_count = 0;
foreach $line (@file) {
        if ((( $line =~ /^.* END /) || ($inblock == 1)) && ($line !~ /^.* START/)) {
                print TMPFILE $line;
                $inblock = 1;
        } elsif ($line =~ /^.* START/) {
                print TMPFILE $line;
                $inblock = 0;
                if ($sec_count == numsecs){
                        last;
                }else{
                        $sec_count = $sec_count + 1;
                }
        }
}
close (INFILE);
close (TMPFILE);
open (TMPFILE, "</tmp/tmpfile");
@file2 = reverse <TMPFILE>;
foreach $line (@file2) {
        print $line;
}
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now