1

I am trying to grep for 5 lines before and after a match. Since I am using AIX I do not have the GNU feature of :

grep -B 5 -A 5 pattern file

Is there a way to do this with grep, awk, perl, sed, something else? Can I please get a one liner? I am trying to do this across multiple servers.

Adding more information:

$ cat b.txt
100
101
102
103
104
Successful
105
106
107
108
109
110
111
112
113
114
115
116
Successful
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
Successful
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
Successful
154
155
156
157
$ grep -B 5 -A 5 Successful b.txt
100
101
102
103
104
Successful
105
106
107
108
109
--
112
113
114
115
116
Successful
117
118
119
120
121
--
129
130
131
132
133
Successful
134
135
136
137
138
--
149
150
151
152
153
Successful
154
155
156
157
$
6
  • I don't think either of the answers at Grep line after/before -A/-B substitution in AIX is a good one for the OPs case.
    – Ed Morton
    Jul 19 at 22:54
  • 1
    Please edit your question to include concise, testable sample input and expected output so we can best help you. Include overlapping ranges and ranges too close to the start/end of the input if those can occur.
    – Ed Morton
    Jul 19 at 23:04
  • 2
    Can you explain the need for a one-liner?
    – Jeff Schaller
    Jul 20 at 17:16
  • @EdMorton does that give the information you need? I did it in a Linux environment. Unfortunately I am working in an AIX environment.
    – cokedude
    Aug 3 at 19:27
  • @JeffSchaller does that give the information you need?
    – cokedude
    Aug 3 at 19:28
3

Using any awk in any shell on every Unix box:

$ seq 20 | awk -v b=5 -v a=5 '/10/{for (i=(NR-b > 0 ? NR-b : 1); i<NR; i++) print buf[i%b]; c=a+1} {buf[NR%b]=$0} c&&c--'
5
6
7
8
9
10
11
12
13
14
15

As @Quasimodo pointed out in the comments the above doesn't behave exactly like grep for overlapping ranges:

$ seq 20 | grep -B 5 -A 5 -E '^[57]'
1
2
3
4
5
6
7
8
9
10
11
12

so here's an alternative:

$ seq 20 | awk -v b=5 -v a=5 '/^[57]/{for (i=NR-b; i<NR; i++) { j=i%b; if (j in buf) print buf[j]; delete buf[j] } c=a+1} { if ( c&&c-- ) print; else buf[NR%b]=$0 }'
1
2
3
4
5
6
7
8
9
10
11
12
1

Not the answer you're looking for? Browse other questions tagged or ask your own question.