How to Use Vim to Replace Text in Multiple Files
Use vim macros and regex replace to speed up your editing
Problem
You're refactoring a codebase and you need to make the same change across all files:
function greeter() {
return 'Hello World!';
}
In the example above, we want to rename greeter
to greet
. Because we're changing the name of the function where it's defined, we need to rename it everywhere it's used as well.
Solution
With vim, you can use a macro to record how to change the function name and then repeat that change across all files.
In this case, the action we're going to repeat is a regular expression search and replace.
TL;DR
Before we go through an in-depth explanation about each step, here's a TL;DR and a video that shows the process in action:
vim **/*.js
- tell vim to open all JavaScript filesqa
- start recording a macro and store it in thea
register:%s/greeter/greet/g
- replacegreeter
withgreet
in a single file:wnext
- write the file and move to the next file in the listq
- end the macro recording@a
- replay the macro for the next file999@a
- replay the macro for the next 999 files (this will end early once the last file is reached)
How To
Great. Now that you know what we're trying to accomplish, let's take a look at how it works in-depth.
1. Open Vim With An Argument List
There are many ways to open vim.
vim
- opens vim to the startup pagevim test.js
- opens vim and loads the filetest.js
vim **/*.js
- opens vim with all JavaScript files stored in a list
By using the 3rd option, you can force vim to keep track of all JavaScript files.
Once you're done editing the first file, you can type :wnext
to write the file and move to the next file in the list.
2. Start the macro
Macros are a way to record a set of actions, store them, and then replay them on command.
To start a macro:
- Press the
q
key - Press any other key (the macro will be stored to that key's register)
In this case, we'll press qa
to start the recording and store the macro in the a
register.
3. Regex Replace
In vim you can replace a string in a file by using a regular expression.
We'll type the following to do this: :%s/greeter/greet/g
.
Let's break down the above:
%s
- this tells vim to apply the change within the entire file/greeter/
- this is the text we want to change/greet/
- this is the text we want to change tog
- this is a global flag (without this, vim will only replace the text once per line)
4. :wnext
Once we've edited the file, we need to write (save) the file and then go to the next file in the list.
Enter the command :wnext
to do this.
5. End the Macro
At this point, we've finished all the steps that we want to save in our macro:
- Change the string
greeter
togreet
- Write the file
- Move to the next file in the list
To stop the recording, you just need to press the q
key again.
6. Replay the Macro
Now that we've recorded the macro, we can replay the steps above to automatically change the text and move to the next file.
You can replay a macro by pressing @a
.
There's nothing special about a
. It's just the register which is storing the macro. If we had used the register f
instead of a
above then you'd need to press @f
to replay the macro.
7. Replay the Macro x 999
If step 6 succeeded without any errors then it should be safe to replay the macro for the remaining files.
We can take advantage of a vimism which is to enter a number before a command and then type the command. This will tell vim to repeat that action the number of times you entered.
For example, it's common knowledge that to move around a file, you can press j
, k
, h
, l
to move the cursor over in one direction.
However, if you press 5j
this will tell vim to repeat the move down action 5 times.
We can use a similar trick here and re-run the macro a large number of times.
Press 999@a
to re-run the macro stored in the a
registry 999 times.
You probably don't have 999 files, but vim will go through every file until it reaches the end. Once it reaches the end, it'll throw an error saying that there are no more files. This error will stop the 999 repeat that we started earlier.
By using the error strategically, we can just repeat the macro a large number of times which will have the effect we want.