19

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!

3
  • 2
    Now that you have some answers to your question, it's encouraged to upvote any good answers, and to accept one (if you feel it answered the Q well enough). As usual romainl's answer is better than mine :) Commented Nov 17, 2021 at 17:30
  • 1
    Just two different but valid approaches. Commented Nov 17, 2021 at 19:13
  • There's probably an answer somewhere on using :bufdo as well. You can start with :set awa (all write all) which will save all changed files without interrupting the process and then :bufdo %s/<match-string>/<replace-string>/ge which will replace multiple occurrences on all lines and keep going even on errors (no match found). Commented Aug 16, 2024 at 5:16

3 Answers 3

34

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
Sign up to request clarification or add additional context in comments.

3 Comments

This worked too. Thank you very much for your help; I like the fact this allows you to operate on each match.
I feel like doing :cfdo %s/foo/bar/gc can have unexpected effects as opposed to :cdo s/foo/bar/gc because the former does the change file-wide and the later does it only on the entries visible in the quickfix list. But this can be rare as an instance in the file is most likely in the quickfix list.
@RaZ0rr I also prefer :cdo over :cfdo.
6

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.

2 Comments

Worked a treat, thank you very much for this! Looks like a brilliant screen cast series as well, can't believe I haven't bumped into this yet.
@John_L_Smith Glad it helped - The guy behind the screen cast series also has a book 'Practical Vim by Drew Neil' which is well worth a read (there is also a second one, 'Modern Vim', but I think it's less useful).
1

I just wanted to add to the answer by mattb, that this is specifically discussed in Section 26.3 of the manual.

As a brief example:

:args *.c
:argdo %s/old_pattern/new_pattern/ge | update

The first command selects the files to apply the change to, while the second applies the change. In more detail:

  • %s changes all lines in a file.
  • ge carry out the change to all instances per line in a file, suppressing any errors.
  • update writes the file, if it was changed.

Analogs exist for making such changes across all windows or all buffers. More details in the manual.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.