I need to print 5 lines after the "tail" key word...
Why didn't you say so in the first place? That would change how people answer the question.
and I don't understand why are there's 2 tests for tail and 2 print commands ?
Well, actually, there's no need for the duplication. The following would work just as well -- and would cover your little "amendment" to the original spec:
#!/usr/bin/perl
use strict;
my $inputfile = shift;
my $withinBlock = 0;
open (IN, "<$inputfile") || die "could not open inputfile\n";
while (<IN>) {
if (/head/) {
$withinBlock = 6;
}
if ($withinBlock) {
print $_;
$withingBlock-- unless $withinBlock == 6;
}
if (/tail/) {
$withinBlock = 5;
}
}
close (IN);
Note that if there is a new "head" line within the five lines that follow a "tail", the $withinblock state variable gets reset to 6, and will stay there till the next "tail". If there is no "head" within the next five lines, it will decrement to 0, turning off the output.
Another "feature" of this version is that if there is a "tail" line without a previous "head", the five lines following "tail" will still get printed. One more thing: since the head and tail regexes are not anchored, the logic will fire whenever these words happen to show up in the data -- e.g:
blah blah
head
This is a bunch of text in a target block.
It includes excerpts from a book on animals,
which have tails. So this line will cause the
output to be turned off
after the next
five
lines,
i.e. here.
So you won't get to see this line
or this one.
tail
But you'll see this one
and
these
lines
too.
Now the output is off again, but since we're taking
about animals, which all have heads, the output is now
on again, and you see the previous and current lines,
as well as this and the next two...
|