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

How do I run a macro only on lines that match a specific pattern?

Answer

:g/pattern/normal @a

Explanation

The :g (global) command combined with :normal @a lets you execute a recorded macro only on lines matching a pattern. This is surgical automation — instead of running a macro on every line or manually jumping between matches, you let Vim find the targets and apply the macro in one shot.

How it works

  • :g/pattern/ selects every line in the file that matches pattern
  • normal @a runs the macro stored in register a as a normal mode command
  • Vim processes each matching line one at a time, positioning the cursor at the beginning of the line before executing the macro
  • Lines that do not match the pattern are completely untouched

Example

Suppose you have a CSS file and you want to double every pixel value, but only on lines containing margin:

margin: 10px;
padding: 20px;
margin: 5px;
border: 1px solid;
margin-top: 15px;

First, record a macro that doubles the number on the current line:

qa0/\d\+<CR>ciw<C-r>=submatch(0)*2<CR><Esc>q

Or more simply, if there is one number per line:

qa0f:w<C-a>q

Then apply it only to margin lines:

:g/margin/normal @a

The padding and border lines remain unchanged.

Tips

  • Use :g!/pattern/normal @a or :v/pattern/normal @a to run the macro on lines that do not match
  • The macro runs with the cursor at column 1 of each matching line, so design your macro to work from the beginning of a line
  • Use norm! instead of normal to ignore custom mappings and use default Vim behavior — this is safer and more predictable
  • You can chain this with ranges: :10,50g/pattern/normal @a limits execution to lines 10 through 50
  • If the macro modifies line numbers (e.g., deletes or adds lines), :g may behave unexpectedly because it pre-scans line addresses — test on a small range first
  • Combine with :w afterward to save: :g/pattern/normal @a | w
  • This technique effectively replaces many complex :s commands — sometimes a macro is easier to record than a regex is to write

Next

How do I edit multiple lines at once using multiple cursors in Vim?