Select last block from a file

Hi,

I have to always select last portion of a block identified by 2 fixed keywords
which repeats in a file for eg

START
....
...
END

START
....
...
END

START
....
...
END

THE LAST PORTION WITHIN (START AND END) SHOULD ALWAYS BE SELECTED

python alternative:
INput:
START
1st
END

START second block
second
END

START third block
last
END

store =[]
data = open("input").readlines() #each file into array
for i in data[::-1]: #starting from last entry, work backwards
        i = i.strip() #strip leading/trailing spaces
 	if i.startswith("END"):continue
 	elif i.startswith("START"):break
 	else: store.append(i) 
print ''.join(store[::-1]) #reverse result back..

output:

last

#! /usr/bin/perl

$file='last_block'; #file name
open (FH, $file);

while ($line=<FH>) {
undef(@array);
chomp($line);
if($line =~ /^START/) {
while ($temp = <FH>) {
chomp($temp);
if ($temp =~ /^END/) {
last;
}
push(@array, $temp);
}
@copy=@array;
}
}
print "@copy\n";

input file (last_block):
START
i am in first block
Now tell me i am...
END

START
i am in second block
now tell me i am
...
END

START
I am last block
did u asked me
END

output:
I am last block did u asked me

#!/bin/bash
file=input
line_no=1

total=`cat $file | wc -l`
state=0

while [ $line_no -le $total ]
do
line=`tail -$line_no $file | head -1`

    if [ "$line" = "END" ]
    then
            state=1
    elif [ "$line" = "START" ]
    then
            break
    elif [ $state -eq 1 ]
    then
            output=$line"\\n"$output
    fi

    line_no=\`expr $line_no \+ 1\`

done

echo -e $output

$ more test.pl
#!/usr/bin/perl -w

$file="test.txt";

open(FH,$file) || die "Unable to open $file : $!\n";

my $line;
my $strt_str=0;
my @arr=();

while ( $line = <FH> )
{
chomp $line;

    if\( $line =~ /^START/  \) \{
            @arr = \(\);
            $strt_str = 1;
    \}

    push\(@arr,$line\) if\( $strt_str == 1 \);

    $strt_str = 0 if \( $line =~ /^END/ \);

}

print join("\n",@arr)."\n";

$ more test.txt
START
i am in first block
Now tell me i am...
END

START
i am in second block
now tell me i am
...
END

START
I am last block
did u asked me
END

$ perl test.pl
START
I am last block
did u asked me
END

the keywords START and END
are not the only words in the line so the code fails

START .........................
.....
.....
.....
......
END ............................

I only know that the keywords wil be START and END but there can be other chars in the line

Another way using awk:

awk '
     /^START/ { inside = 1 ; count = 0; next}
     /^END/   { inside = 0 ;next}
     inside  { line[count++] = $0 }
     END     { for (i=1; i<=count; i++) print line }
    ' input_file

Jean-Pierre

Can this awk statement be modified if the 2 keywords can be preceded by blank spaces before them ?

Just remove "^" from the all the above scripts if you feel that "START" can be anywhere in the line.

Read man awk or some perl documentation.....

Hi Jean-Pierre,

I hv modified ur code to work on the file.

Input file: input.txt
START
i am in first
block
Now tell me i am...
END

START hello
i am in second
block
now tell me i am
...
END

START vvvvvvvvvvvvvv END hello START
I am last block
did u END asked me
hello is it START correct
hello END hi
End

code:

sed 's/ START/\nSTART/' input.txt | sed 's/START /START\n/' | sed 's/ END/\nEND/' | file.awk

where file.awk:
awk '
/^START/ { inside = 1 ; count = 0;}
/^END/ { inside = 0 ; }
inside { line[count++] = $0;}
END { for (i=1; i<count; i++) print line [i]}
'

output:
correct
hello