Find and Replace Text in Vim

How do you search for a text in Vim?

Press the / key, type your search text and press enter. This is just like the less command.

But this method of finding text doesn't allow you to replace the found result.

Let me share how you can find and replace in Vim.

:%s/foo/bar/gci

The above command will run a case-insensitive search to find all the occurrences of your search term (foo) with the new term (bar). With the flag c, it asks to confirm before replacing any substitution.

Let me go into detail and explain things more clearly.

Using the substitute command to find and replace text in Vim

I guess you already know that to run a command in Vim, you must be in the normal mode (also known as command mode). Press Esc key to enter this mode.

Vim has a handy command :substitue, can also be used with the shorter version :s.

Below is the general syntax of the substitute command:

:[range]s/{pattern}/{string}/[flags] [count]

Let's break down this syntax. Anything between the square brackets '[]' is optional.

  • range : This part of the syntax can be used if you want the substitution between said lines. If you do not mention a range, it will only substitute text on the current line. (I have shared a table for range)
  • pattern : Here is where you specify the text that you want to replace.
  • string : This is the string which will replace the pattern.
  • flags : To replace all occurrences of the search pattern, use the g flag. You can specify if you want the match to ignore case, use i flag. To manually confirm each search and replace operation, use the c flag.
  • count : Number of lines to replace text in.
Range Description
. Current line
$ Last line
% All lines
x Line number x
.,+x From current line until additional x lines

Examples of finding and replacing in Vim

Let's go over a few examples that demonstrate the use of the substitute command in Vim.

Below is the screenshot of the file I will be using to demonstrate the usage of substitute command in Vim.

Basic text replacement

For this example, I made sure that the string 'Hello' occurred several times in at least one line and multiple times in the file.

I want to replace 'Hello' with the string 'HI'. Below is the Vim command to do that:

:%s/Hello/HI/g

Replace with confirmation

To substitute text, but want a confirmation every time you do it, you can use the c in the substitute command.

:%s/Hello/HI/gc

As you can see from the video, Vim asks me for a confirmation every single time before it substitutes a pattern.

You also have a prompt that looks like the following line:

replace with HI (y/n/a/q/l/^E/^Y)?

The options from the prompt have the following meaning:

  • y: yes
  • n: no
  • a: all
  • q: quit without substituting, but it does not undo once you have already substituted text
  • l: substitute this and exit (think of 'last')
  • ^E: Scroll up (does not work in vim-tiny)
  • ^Y: Scroll down (does not work in vim-tiny)

Case-insensitive replacement

When you want to substitute text regardless that if it is in uppercase or lowercase, in that case (haha) you should use the i flag in the substitute command.

:%s/hello/HI/gi

If you notice, all occurrences of 'hello' or 'Hello' and even 'hELLO' are replaced with 'HI'. This is a case insensitive pattern substitution.

Every 'hello' is replaced with 'HI' even though most 'hello' have an uppercase 'H' in it.

Replace text in single line in Vim

To substitute text in a single line, we need to specify the range that limits the scope of substitution to the current line.

For that, it is better to use the . range descriptor.

:.s/Hello/HI/g
Look how only the first line got affected

As you can see, only the pattern in the first line got substituted because I used the period '.' range descriptor.

Bonus tip: Using a different delimiter

Looking at the syntax of the substitute command, I mentioned that the pattern and string are separated by a forward slash '/'.

But what if you had text with lots of forward slashes in pattern/string, like a path, that repeated everywhere in the file? Escaping forward slashes can be tedious and it can be easily missed sometimes.

So, instead of using the forward slash character as a delimiter, you can use a different delimiter instead.

A few delimiter characters that I have seen being used are #, _ and @.

Here is a gif that shows demonstration of using @ as a delimiter instead of /.

Conclusion

Substituting text can be a common occurrence and Vim has you covered with a powerful way to search and replace patterns with a string. You can even mix regex in Vim's substitution command.

If you are interested in learning more than just the Vim Basics, I highly recommend using this program by Jovica Ilic.

Mastering Vim Quickly - Jovica Ilic
Exiting Mastering Vim Quickly From WTF to OMG in no time