How do I run a command on lines near each match, not just the matching line itself?
Answer
:g/pattern/.-1,.+1d
Explanation
The :g (global) command normally operates on lines that match a pattern. But you can use range offsets to target lines around each match instead. This is powerful for deleting, joining, or modifying context lines surrounding a pattern.
How it works
:g/pattern/— finds every line matchingpattern.-1,.+1— creates a range from 1 line above (.−1) to 1 line below (.+1) relative to the matched lined— deletes that entire 3-line range
The . in the range refers to the current matched line. You can use any offset: .-2,.+3 targets 2 lines above through 3 lines below.
Example
Given this log file:
timestamp: 10:00
DEBUG: entering function
timestamp: 10:01
ERROR: null pointer
timestamp: 10:02
DEBUG: exiting function
Running :g/DEBUG/.-1,.+1d removes each DEBUG line along with the timestamp above and below it, leaving only the ERROR block.
Tips
- Use
:g/pattern/.+1dto delete only the line after each match - Combine with
joininstead ofd::g/pattern/.,. +1joinmerges each match with the next line - The offsets are processed top-to-bottom, so overlapping ranges may cause unexpected behavior — use
:g/pattern/.-1,.+1don non-adjacent matches for best results - Use
:g/pattern/.,$dto delete from each match to the end of the file (stops at first match)