aprin
aprin

Reputation: 123

Match first pattern and get all output after n'th match of other pattern

How about matching and then getting the output after n'th match of other match? Meaning:

    boo <-first match pattern
    art <- second pattern
    foo
    art
    art
    two

I want to get "boo" and everything until 2nd occurence of "art":

    boo
    art
    foo
    art

Plus, if the second pattern is a blank/newline, how do we do it? ;) awk would be interesting..

Thanks!

Upvotes: 1

Views: 55

Answers (3)

Jeff Y
Jeff Y

Reputation: 2456

awk knows the line number, so:

awk 'NR==2{p2=$0}{print}NR>2&&$0==p2{exit}'

Or, if boo is some fixed pattern but art is whatever comes after boo:

awk '$0=="boo"{n=NR}n&&NR-n==1{p2=$0}{print}n&&NR-n>1&&$0==p2{exit}'

Or if both boo and art are fixed patterns:

awk '$0=="boo"{n=NR}n&&NR-n==1&&$0=="art"{p2=$0}{print}n&&NR-n>1&&$0==p2{exit}'

And finally, if the first boo and art don't need to be adjacent and you want to (repeatedly) print all blocks of lines (and only those lines) inside the pattern "boo...art...art":

awk '!n&&$0=="boo"{n=1}n{print}n==2&&$0==p2{n=0}n==1&&$0=="art"{n=2;p2=$0}'

Upvotes: 0

zdk
zdk

Reputation: 1576

Actually, this kind of manipulating is quite easy with Awk. I think you have chosen the right tool. But blindly use the tool is worse, I guess you can check some basics of Awk http://goo.gl/NkUP3y instead of googling one-liner solution or sort.

Here is my quick test to serve your requirement and it works.

⇒ cat test
boo
art
foo
art
art
two
⇒ awk 'BEGIN {m2=0} /boo/ {m1=1; print; next} { if ($1 ~ /art/) { if (m2==1) {print; exit} else { m2=1 }  }  } { print }' test
boo
art
foo
art

Hopefully it is what you want.

Upvotes: 0

Paul Evans
Paul Evans

Reputation: 27567

Use awk something like this:

awk 'BEGIN{s1=s2=0} $1=="boo"{s1=1} s1==1 && s2<2 {print} $1=="art"{s2++}'  file.txt

Upvotes: 1

Related Questions