Find and replace all instances of specific string in multiple files in vim

Viewed 385

I'm still relatively new to Vim and can't figure out how to replace all instances of a specific string in multiple files (from a specific project directory). Ideally I want to do this without any additional plugins; was looking into :vimgrep and :arg options but can't work it out.

Thanks for your time in advance!

2 Answers

The general workflow is:

  1. Search for your pattern across the project.
  2. Operate on each match (safer, slower) or on each file with matches (riskier, faster).
  3. Write your changes.

The first step can be done with any command that populates the quickfix list: :help :vimgrep, :help :grep, something from a third-party plugin, etc.

Taking :grep as an example:

:grep foo **/*.js

will populate the quickfix list with an entry for every foo found in *.js files in the current directory and subcategories. You can see the list with :cwindow.

The second step involves :help :cdo or :help :cfdo:

:cdo s/foo/bar/gc

which will substitute every foo with bar on each line in the quickfix list and ask for confirmation. With :cfdo it would look like that:

:cfdo %s/foo/bar/gc

If you are super confident, you can drop the c at the end. See :help :s_flags.

The third step involves :help :update:

:cfdo update

which will write every file in the quickfix list to disk if they have been changed.

In short:

:gr foo **/*.js
:cdo s/foo/bar/gc
:cfdo up

You can run a standard substitute command on all lines of all files of the arg list like so:

:argdo %s/pattern/replacement/ge

And if you want to add all files from a particular directory to the arg list, you can use:

argadd `path/to/dir/*.py`

Notice the backticks in the above example.

See a good series of screen casts about how to do more here and see this episode in particular.

Related