0

I have a file containing lines, like this:

some strings here class="batch2010" some more strings here click-here
<about 20-30lines here>
some strings here class="batch2006" some more strings here click-here
<about 20-30lines here>
some strings here class="NA" some more strings here click-here
<about 20-30lines here>
some strings here class="batch2010" some more strings here access-denied
<about 20-30lines here>

I want to print the line that contains:

class="batch2010"

but NOT:

access-denied

in the same line and then print the next 10 lines in the file.

Is there any other way, other than having to write a really long and complex shell script?

askmish
  • 6,464
  • 23
  • 42
  • 1) what about line with access denied in the following line that are elligible ? 2) what about several elligible line in 10 following line of one occurance (print each separately or until the 10 last after last elligible in the block or only part until next 10 line and not a new occurence, ...) ? – NeronLeVelu Aug 01 '14 at 08:41
  • @NeronLeVelu Chances that the line with access-denied will occur in the next 10 lines is none. So, it automatically does mutually exclusive. – askmish Aug 01 '14 at 08:45

4 Answers4

2

You can try

< thefile grep -v 'access-denied' | grep -A10 'class="batch2010"'
damienfrancois
  • 52,978
  • 9
  • 96
  • 110
  • Not very sure if this is exactly what the OP is asking for. What there is a line containing `access-denied` within the next 10 lines after `class="batch2010"`? Then, that line won't be printed while it should. – fedorqui Aug 01 '14 at 08:23
  • 1
    I agree. If the OP makes that case explicit, I'll remove my answer. – damienfrancois Aug 01 '14 at 08:30
2

This can be a solution:

awk 'lines>0 {print; --lines}
     /ass="batch2010"/ && !/access-denied/ {lines=10}' file

See output (not very relevant, as there are not many lines):

$ awk '(lines>0) {print; --lines} /ass="batch2010"/ && !/access-denied/ {lines=10}' a
some strings here class="batch2006" some more strings here click-here
some strings here class="NA" some more strings here click-here
some strings here class="batch2010" some more strings here access-denied

Its logic is based on How to print 5 consecutive lines after a pattern in file using awk adding the part in which we match ass="batch2010" and "unmatch" access-denied.

Test

$ seq 30 > a
$ awk 'lines>0 {print; --lines} /4/ && !/14/ {lines=10}' a
5
6
7
8
9
10
11
12
13
14
25
26
27
28
29
30
Community
  • 1
  • 1
fedorqui
  • 275,237
  • 103
  • 548
  • 598
0

This might work for yoyu (GNU sed):

sed -n '/access-denied/b;/class="batch2010"/{:a;$!{N;s/\n/&/10;Ta};p}' file

Bail out if line contains access-denied otherwise if line contains class="batch2010" read in the next 10 lines and print them out.

potong
  • 55,640
  • 6
  • 51
  • 83
0

This sed command should work
Sed in non-printing mode.
if it finds denied, breaks and jumps to end of sed statement.
If not looks for 2010 and prints the next 10 lines

sed -n '/denied/b;/2010/,+10p' file