← Back to DevBytes

Vim Find and Replace: Complete Guide

Vim Find and Replace: Complete Guide

Find and replace is one of the most frequently used operations in any text editor, and Vim offers one of the most powerful implementations available. Whether you are renaming a variable across an entire codebase, fixing a recurring typo, or transforming data with regular expressions, mastering Vim's substitute command will dramatically speed up your workflow. This guide walks you through everything from the basics to advanced techniques, with practical examples you can apply immediately.

What Is Vim Find and Replace?

In Vim, find and replace is performed using the :substitute command, almost always abbreviated as :s. The command searches for a pattern within a specified range of lines and replaces each match with replacement text. Because Vim uses its own regex engine, the substitute command can handle everything from literal string replacements to complex pattern-based transformations.

The general syntax of the substitute command is:

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

Each part of this syntax plays a specific role. The range determines which lines are affected, the pattern defines what to search for, the replacement defines the new text, and the flags control how the substitution behaves.

Why It Matters

Efficient find and replace is essential for productive editing. Consider the alternatives: manually scrolling through a file to change each occurrence is error-prone and slow, while leaving your editor to use external tools breaks your concentration. Vim's substitute command keeps you in the editor, works across multiple files, supports confirmation prompts, and integrates with Vim's search history. For developers working on large projects, these capabilities are not just conveniences — they are essential tools for maintaining velocity.

Basic Find and Replace

Replacing on the Current Line

The simplest form of the substitute command operates on the current line only. For example, to replace the first occurrence of foo with bar on the line where your cursor is located, type:

:s/foo/bar/

By default, this replaces only the first match on the line. If the line contains multiple instances of foo, the rest remain unchanged.

Replacing All Occurrences on the Current Line

To replace every occurrence on the current line, add the g (global) flag:

:s/foo/bar/g

This is one of the most common substitutions you will use. The g flag tells Vim to continue searching the line after each replacement, rather than stopping at the first match.

Replacing Across the Entire File

To perform a substitution across the whole file, use % as the range. The % symbol represents all lines in the file:

:%s/foo/bar/g

This replaces every occurrence of foo with bar throughout the entire file. This is the command most developers memorize first, and it covers the majority of find-and-replace needs.

If you want to see a count of how many substitutions were made, add the n flag alongside g — but note that n actually reports the count without performing the replacement. To report the count after replacing, simply read the message Vim prints at the bottom of the screen.

Working with Ranges

Replacing Within a Line Range

You can specify an explicit line range using line numbers. For example, to replace foo with bar on lines 10 through 20:

:10,20s/foo/bar/g

Replacing from the Cursor to the End of the File

The . symbol represents the current line, and $ represents the last line. To replace from your cursor position to the end of the file:

:.,$s/foo/bar/g

Replacing Within a Visual Selection

When you select text in visual mode and press :, Vim automatically inserts the range '<,'>, which represents the start and end of your selection. You can then complete the substitute command:

:'<,'>s/foo/bar/g

This is extremely useful when you only want to affect a specific block of code.

Replacing in the Entire Buffer with Confirmation

To replace across the whole file but confirm each change individually, add the c (confirm) flag:

:%s/foo/bar/gc

Vim will highlight each match and prompt you with options like y (yes), n (no), a (all remaining), q (quit), l (last), and ^E / ^Y to scroll. This is invaluable when you want to review changes before committing them.

Understanding Flags

Flags modify the behavior of the substitute command. Here are the most important ones:

You can combine flags freely. For example, to perform a case-insensitive, confirmed, global replacement:

:%s/foo/bar/gic

Regular Expressions in Substitutions

Basic Pattern Matching

Vim's substitute command supports regular expressions in the search pattern. For example, to match one or more digits, use \d\+:

:%s/\d\+/NUMBER/g

Note that in Vim's default regex mode, the + quantifier must be escaped as \+. This differs from Perl-style regex where + works without escaping.

Capturing Groups and Backreferences

You can capture parts of the match using escaped parentheses \( and \), then reference them in the replacement with \1, \2, and so on. For example, to swap two words separated by a comma:

:%s/\(\w\+\),\s*\(\w\+\)/\2, \1/g

This transforms apple, banana into banana, apple.

Using Very Magic Mode

To avoid escaping special characters, you can enable "very magic" mode by starting your pattern with \v. In this mode, characters like +, (, ), and { have their standard regex meanings without escaping:

:%s/\v(\w+),\s*(\w+)/\2, \1/g

This produces the same result as the previous example but is much easier to read.

Case Conversion in Replacements

Vim allows you to change the case of matched text in the replacement string using special sequences:

For example, to capitalize the first letter of every word in a file:

:%s/\v(\w+)/\u\1/g

Practical Examples

Renaming a Variable

To rename a variable named oldName to newName across an entire file, use word boundaries to avoid partial matches:

:%s/\<oldName\>/newName/g

The \< and \> sequences match word boundaries, ensuring that oldNameExtended is not accidentally changed.

Removing Trailing Whitespace

Trailing whitespace is a common source of unnecessary diffs. To remove it across the entire file:

:%s/\s\+$//e

The \s\+$ pattern matches one or more whitespace characters at the end of a line, and the e flag suppresses errors if no trailing whitespace exists.

Converting Tabs to Spaces

To convert all tab characters to four spaces:

:%s/\t/    /g

Adding a Prefix to Every Line

To add a comment marker to the beginning of every line in a file:

:%s/^/# /

The ^ anchor matches the start of each line.

Replacing Across Multiple Files

Vim can perform substitutions across multiple files using the :argdo or :bufdo commands. First, populate the argument list with the files you want to modify:

:args **/*.js

Then run the substitution on every file in the argument list:

:argdo %s/oldFunction/newFunction/g | update

The update command saves each file only if it was modified. Be careful with multi-file substitutions and always review changes with git diff afterward.

Best Practices

Conclusion

Vim's find and replace capabilities go far beyond simple text substitution. By understanding ranges, flags, regular expressions, and multi-file operations, you can transform text with precision and speed that few other editors can match. Start with the basic :%s/old/new/g command, then gradually incorporate confirmation flags, word boundaries, and very magic mode as your confidence grows. With practice, these commands become second nature, and you will find yourself making complex edits in seconds that would otherwise take minutes of manual work. The key is to experiment in a safe environment, build muscle memory, and always verify your changes before saving.

— Ad —

Google AdSense will appear here after approval

← Back to all articles