perl -lne ' eof and !$a && print "$ARGV: ", 0+$a; # no DONEs => ans=0 next unless /DONE/ && !$a ... /DONE/; # skip non-DONE ranges /DONE/ and !$a++ && next; # begin DONE range !/DONE/ and !eof and $a++,next; # middle of DONE range !/DONE/ and eof and $a=2; # lone DONE => ans=0 print "$ARGV: ", ($a-2, $a=0, close ARGV)[0]; # end of DONE range # at the end we do 4 things: 1) subtract 2 from sum, 2) print filename+sum, 3) reset sum, and 4) skip the current file and jump to the next file in queue. ' ./*.txt With sed we can do this on a per-file basis:
for f in ./*.txt; do printf '%s: %d\n' "$f" "$(sed -e '/DONE/,/DONE/!d; //d' "$f" | wc -l)" done The difference will be in the scenario when we shall not be having a closing DONE.