4

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.

8

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
2

If you accept perl as a command line tool, you can also

perl -ne 'print unless $c>2; ++$c if /foo/' 
perl -ne '++$c if /foo/; print unless $c>2' 

with/without keep.

  • The example had only 3 foos but if more ever occur you need unless $c>=3 – dave_thompson_085 Jul 31 '16 at 9:10
  • True, of course. Thanks for spotting---fixed. – waku Sep 19 '16 at 16:52
1

Alternative answer: you could do this from vim. You could do this with vim as a text editor, or as a command line tool. As a text editor (with and without the line):

/foo<cr>2ndG:wq<cr>
/foo<cr>2njdG:wq<cr>

Some important details: <cr> means "enter". Also, you should in general do <n-1>ndG to delete after the "N'th" occurence. You asked for 3, so I wrote 2 in the example.

You could also do this purely from the command line.

vim -c "/foo" -c "normal 2ndG" -c "wq"
vim -c "/foo" -c "normal 2njdG" -c "wq"

This approach will also work with regular expressions. This site provides a nice explanation of the vim flavor of regex.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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