How do I run a command on every line in the quickfix list at once?
Answer
:cdo {cmd}
Explanation
:cdo executes an Ex command on every entry in the quickfix list in sequence, visiting each match in turn. Combined with :vimgrep or :grep, it enables precise, line-targeted transformations across an entire project — without touching lines that were not matched.
How it works
:cdo— iterate over each quickfix entry (one per matched line) and run{cmd}on it- This is distinct from
:cfdo, which iterates per file in the quickfix list. Use:cdowhen you want line-level control; use:cfdowhen you want to run a whole-file%s///on each affected file.
Typical workflow:
:vimgrep /old_api/gj **/*.py
:cdo s/old_api/new_api/g | update
:vimgreppopulates the quickfix list with every match:cdo s/old_api/new_api/gperforms the substitution on each matched line| updatesaves files that were modified
Example
Find all TODO comments and append a date:
:vimgrep /TODO/gj **/*.md
:cdo s/TODO/TODO (2026-01-01)/g | update
Only lines containing TODO are modified — untouched lines in those files stay exactly as they are.
Tips
- Add the
eflag to:substituteto suppress "pattern not found" errors on entries where the pattern doesn't match::cdo s/old/new/ge | update - Use
:ldoto do the same with the location list instead of the quickfix list - Open the quickfix window with
:copenfirst to review matches before running:cdo - Combine with
:cfdo updateafterward if you prefer to batch the saves::cdo s/old/new/gthen:cfdo update