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

How do I run a substitution only on lines that match a specific pattern using the global command?

Answer

:g/pattern1/s/pattern2/replacement/g

Explanation

Combining :g with :s lets you apply a substitution using two independent patterns: :g selects which lines to act on, and :s controls what gets replaced within those lines. This gives you precision that :s alone cannot provide, since :s matches both the filter and the replacement using the same regex.

How it works

  • :g/pattern1/ — visits every line in the file that matches pattern1
  • s/pattern2/replacement/g — on each of those lines, replaces all occurrences of pattern2 with replacement

The two patterns are completely independent: pattern1 is the line filter, pattern2 is what you actually want to change.

Example

Suppose you have a JavaScript file and want to change var to let, but only in lines that declare functions:

var x = 1
function foo() { var y = 2 }
var helper = function() { var z = 3 }

Running :g/function/s/var/let/g produces:

var x = 1
function foo() { let y = 2 }
let helper = function() { let z = 3 }

The top-level var x = 1 is left untouched because that line does not match /function/.

Tips

  • Use :g!/pattern1/s/pattern2/replacement/g to invert the filter — substitute only on lines that do not match pattern1
  • Combine with \v (very magic) for cleaner patterns: :g/\vpattern1/s/\vpattern2/replacement/g
  • The /g flag on :s is independent — omit it if you only want to replace the first occurrence per matching line
  • This technique composes with other :g subcommands: :g/pattern/d, :g/pattern/m$, etc.

Next

How do I add more keystrokes to the end of an existing macro without re-recording the whole thing?