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
$
cokedude
  • 1,121
  • 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 '21 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 '21 at 23:04
  • 2
    Can you explain the need for a one-liner? – Jeff Schaller Jul 20 '21 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 03 '21 at 19:27
  • @JeffSchaller does that give the information you need? – cokedude Aug 03 '21 at 19:28
  • You posted a long block of text under "b.txt". If that's sample input then please reduce it to a sensible size where we don't need a scrollbar to read it and add the currently missing expected output. If it's the expected output then add the sample input and, again, make it a sensible size so we don't need scroll bars. – Ed Morton Aug 03 '21 at 21:09

1 Answers1

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
Ed Morton
  • 31,617
  • 1
    If the above answers your question then see https://unix.stackexchange.com/help/someone-answers for what to do next. If it doesn't then feel free to tell us in what was it doesn't and/or ask specific questions. – Ed Morton Aug 03 '21 at 21:12