How do I create a macro that only acts on lines matching a search pattern?
Answer
qa/pattern<CR>dd@aq
Explanation
By starting a macro with a search command, the macro becomes conditional — it jumps to the next match before acting, and terminates when no more matches are found. This creates a targeted macro that skips non-matching lines automatically.
How it works
/pattern<CR>— jump to next match (fails when no more matches exist)- Perform the desired action on that match
@a— recurse to find and process the next match- The macro chain stops when the search wraps around or finds no match
Example
" Delete all lines containing 'DEBUG'
qaq
qa/DEBUG<CR>dd@aq
@a
" Change all 'var' to 'let'
qaq
qa/var<CR>cwlet<Esc>@aq
@a
Before:
const x = 1;
var y = 2;
const z = 3;
var w = 4;
After running the var→let macro:
const x = 1;
let y = 2;
const z = 3;
let w = 4;
Tips
- For simple cases,
:g/pattern/dor:%s/old/new/gare more direct - Macros shine when the transformation is complex (multiple steps per match)
- Use
ninstead of/pattern<CR>if the search is already set - Set
nowrapscanto prevent the search from wrapping::set nowrapscan