Delete from nth occurrence to end of file

text processing

How do you delete from nth occurrence of a pattern to end of file using command line tools like sed?
e.g. delete from the third foo in the following:

something
foo1
maybe something else
foo2
maybe not
foo3 -this line and anything after is gone- 
I'm not here

$sed '/magic/'

Desired result:

something
foo1
maybe something else
foo2
maybe not

Bonus points for the same thing but keeping the line containing the third foo.

Best Answer

Without keeping the line:

awk -v n=3 '/foo/{n--}; n > 0'

With keeping the line:

awk -v n=3 'n > 0; /foo/{n--}'

Though we may want to improve it a bit so that we quit and stop reading as soon as we've found the 3rd foo:

awk -v n=3 '/foo/{n--; if (!n) exit}; {print}' # not-keep
awk -v n=3 '{print}; /foo/{n--; if (!n) exit}' # keep

sed would be more cumbersome. You'd need to keep the count of foo occurrences as a number of characters in the hold space like:

Keep:

sed '
  /foo/{
    x;s/^/x/
    /x\{3\}/{
      x;q
    }
    x
  }'

Not keep:

sed -ne '/foo/{x;s/^/x/;/x\{3\}/q;x;}' -e p
Related Question