Roger Sim
Roger Sim

Reputation: 73

Search and replace in multiple files using vim

Is it possible to apply the same search and replace in multiple files in vim? I'll give an example below.

I have multiple .txt files — sad1.txt until sad5.txt. To open them, I'll use vim sad* and it opened already. Now inside the 5 txt files they have similar word like happy999; I would like to change it to happy111. I am currently using this code:

argdo %s/happy999/happy111/gc | wq!

Eventually only the sad1.txt is changed. What should I do to run one script in the 5 txt files?

Upvotes: 7

Views: 7029

Answers (4)

Babak K
Babak K

Reputation: 469

If you don't need/want to be prompted for confirmation on each search and replace, use the following command, after opening your files with vim sad*:

:argdo %s/happy999/happy111/g | update

You can find more info by looking at the documentation for argdo in vim (:h argdo) or here: http://vim.wikia.com/wiki/Search_and_replace_in_multiple_buffers

Upvotes: 1

Oleg Khalidov
Oleg Khalidov

Reputation: 5268

No doubt, argdo is great, but to type that much boilerplate becomes quite annoying over the time. Give a try to far.vim. It's such a tool that provide many IDEs.

enter image description here

Upvotes: 1

Jonathan Leffler
Jonathan Leffler

Reputation: 753525

Use:

:set aw
:argdo %s/happy999/happy111/g

The first line sets auto-write mode, so when you switch between files, vim will write the file if it has changed.

The second line does your global search and replace.

Note that it doesn't use wq! since that exits. If you don't want to use auto-write, then you could use:

:argdo %s/happy999/happy111/g | w

This avoids terminating vim at the end of editing the first file.

Also consider looking on vi and vim for answers to questions about vi and vim.

Upvotes: 9

grochmal
grochmal

Reputation: 3027

That is a task for sed -i (-i for "in place", works only with GNU sed). Yet, if you really want to use vim or you do need the /c to confirm the replace, you can do it in two ways:

With some help from the shell:

for i in sad*.txt; do
    vim -c ':%s/happy999/happy111/gc' -c ':wq' "$i"
done

(the /c will still work, and vim will ask for each confirmation)

Or with pure VIM

vim -c ':%s/happy999/happy111/gc' -c ':w' -c ':n' \
    -c ':%s/happy999/happy111/gc' -c ':w' -c ':n' \
    -c ':%s/happy999/happy111/gc' -c ':w' -c ':n' \
    -c ':%s/happy999/happy111/gc' -c ':w' -c ':n' \
    -c ':%s/happy999/happy111/gc' -c ':wq' sad*.txt

(In my humble opinion this last one looks horrible and repetitive and has no real advantages over the shell for, but it shows that pure vim can do it)

Upvotes: 1

Related Questions