vimtricks.wiki Concise Vim tricks, one at a time.

How do I delete all blocks of text between two patterns throughout a file?

Answer

:g/start/,/end/d

Explanation

The :g (global) command can operate on ranges, not just single lines. By specifying a range from one pattern to another, you can delete entire blocks of text that span multiple lines. This is a powerful technique for removing HTML sections, code blocks, log entries, or any structured content that has consistent start and end markers.

How it works

  • :g/start/ — matches every line containing "start"
  • ,/end/ — extends the range from each match to the next line containing "end"
  • d — deletes the entire range (both marker lines and everything between them)
  • Vim processes matches from top to bottom, adjusting line numbers as deletions occur

Example

Before:

keep this line
<!-- BEGIN GENERATED -->
generated content 1
generated content 2
<!-- END GENERATED -->
keep this too
<!-- BEGIN GENERATED -->
more generated stuff
<!-- END GENERATED -->
final line

After :g/BEGIN GENERATED/,/END GENERATED/d:

keep this line
keep this too
final line

Tips

  • Use :g/start/,/end/s/old/new/g to substitute only within matched ranges
  • Use :v/start/,/end/d to delete everything outside the matched ranges
  • Replace d with fold to fold matched ranges: :g/start/,/end/fold
  • Use j instead of d to join the range into a single line

Next

How do I use PCRE-style regex in Vim without escaping every special character?