awk to print before and after lines then count of patterns

What i'm trying to do here is show X amount of lines before and after the string "serialNumber" is found.

BEFORE=3
AFTER=2
gawk '{a[NR]=$0} {count=0} /serialNumber/ && /./ {for(i=NR-'"${BEFORE}"';i<=NR;i++){count++ ;print a}for(i=1;i<'"${AFTER}"';i++){getline; print ; count ++; print count}exit}' datafile 

it's not outputting correctly.

the goal here is to have the awk command do the following:

  1. show the 3 lines that come BEFORE 'serialNumber'
  2. show the actual line containing 'serialNumber'
  3. show the 2 lines that come AFTER 'serialNumber'
  4. show the count of lines found containing 'serialNumber'

if more than one line is found containing 'serialNumber', only steps 1 through 3 should be performed on each line found.

then at the very end of the output, there should be the total number of lines containing 'serialNumber'.

i know its complicated. can this be done?

Deleted. More concise script provided by Chubler_XL on this thread.

1 Like

Can you post a sample of the input file...

We could simplify rdrtx1's the code to:

awk '
{l[NR]=$0;}
/serialNumber/ {c++; t++; for(i=NR-3; i<=NR+2; i++) o=c; next}
{c=0}
END {
   for(i=1; i<=NR; i++) {
       if (o) print l;
       if (o>1 && !(o[i+1]))
            print "cnt: " o;
   }
   print "total count: " t+0;
}
' infile

Never mind then.

Some further testing has highlighted issues when display regions overlap e.g.:

1
2
3
4 serialNumber
5
6
7
8
9
10
11
12
13 serialNumber
14 serialNumber
15
16
17 serialNumber
18 serialNumber
19 serialNumber
20 serialNumber
21

This updated code should display correct "cnt: " subtotals: and uses variables BEFORE and AFTER

awk -v BEFORE=3 -v AFTER=2 '
{l[NR]=$0}
/serialNumber/ {
   c++
   t++
   for(i=NR-BEFORE; i<=NR+AFTER; i++)
      if(i>NR||!o) o=c
}
!o[NR-BEFORE]{c=0}
END {
   for(i=1; i<=NR; i++) {
       if (o) {
           print l
           if (i==NR||o[i+1]<o)
            print "cnt: " o
       }
   }
   print "total count: " t+0
}' infile