Search and Replace in multiple files with Vim

I recently learned a nice VimTrick™ when paring with Arjan. We upgrade an app to Rails 3.2.6 and got the following deprecation message:

DEPRECATION WARNING: :confirm option is deprecated and will be removed from Rails 4.0.
Use ':data => { :confirm => 'Text' }' instead.

Well, nothing difficult about that, but we have quite a few :confirm in this app.

Firstly we checked where we used them (note we use ruby 1.9 hash syntax everywhere):

$ ack -l "confirm:" app

Now you have a listing of all the files that contain the :confirm hash key. You can leave out the -l option to get some context for each find.

Now, we need to open Vim with those files:

$ ack -l "confirm:" app | xargs -o vim

Vim will open the first of these files. Here’s a snippet of what you may find:

= link_to "Delete", something_path, confirm: "Are you sure?"

Now, search and replace is easy:

:%s/confirm: ".*"/data: { & }/g

This will surround the current confirm with the data hash. Just the way Rails likes it. The & character will be replaced with whatever text matched the search pattern.

You could repeat this for every file manually. But, you’re using Vim.

:argdo %s/confirm: ".*"/data: { & }/g | update

This will perform the search and replace on each of the supplied arguments (in this case the files selected with ack) and update (e.g. save) those files.

Now you can quit Vim and enjoy the glory of all the disappearing deprecation warnings.

Note: to do this with the ruby 1.8 hash syntax, just update the search and replace texts accordingly.

I'd love to hear your questions and comments on this article! Mention @ariejan on twitter or shoot me an email.

About Ariejan

Hey! I'm a software engineer building rock solid back-end systems using Ruby, Ruby on Rails and Golang. In my free time I like to repair audio equipment, play the piano and experiment with electronics.