Aman Jain
Aman Jain

Reputation: 11317

How to delete lines around a search pattern in vim?

In a file, I want to be able to delete context around a search pattern.

By context I mean: a) 'n' lines before the pattern b) 'n' lines after the pattern c) 'n' lines after and before the pattern d) do a,b,c by deleting the pattern line as well e) do a,b,c without deleting the pattern line

Is there some way to do it using :g/ or :%s or some other way? I can do this with macros, but that's not what I am looking for.

Here is sample text:

search_pattern random text 1
line below search pattern(delete me)
abc def
pqr stu
...
line above search pattern(delete me)
search_pattern random text 2
line below search pattern(delete me)
...

Upvotes: 13

Views: 9139

Answers (2)

doubleDown
doubleDown

Reputation: 8398

Basically the key is that

  • :d can take a numeric argument after it which specifies the number of lines to delete
  • you can specify an offset after a pattern, e.g. :/patt/+3

Notes:

  • If you're doing this to all instances of pattern, use :g/patt/... instead of :/patt/... (thanks to Peter Rincker for the reminder)
  • all the spaces in the ex commands below are optional, I put it there for the sake of clarity.

To delete n lines before the pattern,

:/patt/-n d n

To delete n lines before the pattern and the pattern line

:/patt/-n d p

where p = n + 1


To delete n lines after the pattern,

:/patt/+ d n

To delete n lines after the pattern and the pattern line

:/patt/ d p

where p = n + 1


To delete m lines before and n lines after the pattern (kinda cheating here since it's 2 commands),

:/patt/-m d m | + d n
  • this works because after the first d command, the cursor will be on the pattern line

To delete m lines before the pattern, the pattern line, and n lines after the pattern

:/patt/-m d q

where q = m + n + 1

Upvotes: 27

Nikita Kouevda
Nikita Kouevda

Reputation: 5746

In each case, it's possible to utilize either a relative range or an offset and an argument to d. The more logically straightforward option depends on the particular case; I tend to use explicit ranges in the inclusive cases (since you can usually omit half of the range), and an argument to d otherwise.

Before the pattern, inclusive:

:g/regex/-3,d
:g/regex/-3d4

Before the pattern, exclusive:

:g/regex/-3,-1d
:g/regex/-3d3

After the pattern, inclusive:

:g/regex/,+3d
:g/regex/d4

After the pattern, exclusive:

:g/regex/+1,+3d
:g/regex/+1d3

Before and after, inclusive:

:g/regex/-3,+3d
:g/regex/-3d7

Before and after, exclusive:

:g/regex/-3,-1d|+1,+3d
:g/regex/-3d3|+1d3

Note that these commands will fail with E16: Invalid range if the range goes past the beginning or end of the file.

Upvotes: 9

Related Questions