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

How do I run a find-and-replace across multiple files at once using the argument list?

Answer

:args **/*.py | argdo %s/old/new/ge | update

Explanation

Combining :args, :argdo, and :update gives you a powerful in-editor multi-file search and replace without leaving Vim. First, populate the argument list with a glob; then :argdo runs any Ex command in each file in sequence; finally :update saves only the files that were actually modified.

How it works

  • :args **/*.py — sets the argument list to all .py files found recursively (** requires path or works directly with :args glob expansion)
  • | chains the next Ex command in the same command line
  • :argdo {cmd} — executes {cmd} in every file in the argument list, loading each in turn
  • %s/old/new/ge — global substitution across the whole file; the e flag suppresses "pattern not found" errors in files where the term doesn't appear
  • | update — after the substitution, write the buffer only if it was changed (:update is like :write but a no-op on unmodified buffers)

Example

" Rename a function across all Python files in the project
:args **/*.py | argdo %s/\<parse_config\>/load_config/ge | update

" Apply to a subset of files
:args src/**/*.js | argdo %s/require(/import(/ge | update

Tips

  • Add set hidden to your config so Vim doesn't complain about unsaved buffers when switching files during :argdo
  • Combine with :argdo normal @a to replay a macro across all files in the list
  • :args with no arguments shows the current argument list
  • :help :argdo for full documentation

Next

How do I enable matchit so % jumps between if/else/end style pairs?