Vim search and replace runs on a handful of commands. I re-ran every command in this guide on Vim 9.1 against a scratch file, so what you read here is what Vim actually does.
You start by finding text, then replace it on one line, across a range, or through the whole file, adding confirmation, case control, and line matching as you go.
New to the editor itself? My Vim tutorial covers modes, saving, and quitting from zero.
Find text with / and ?
Type a forward slash, enter your search text, and press Enter to jump to the next match after the cursor, then use n for the following match and N to step back.
/hello
?hello
The question mark searches the same way but backward toward the top of the file, with n still moving to the next match in that direction and Esc taking you back to normal mode first.
Vim can highlight every match at once, which makes it far easier to judge a search before replacing anything. Turn that view on with one setting and clear it when the color gets distracting.
:set hlsearch
:noh
To replace matches one at a time without the substitute command, search with the slash, type cgn plus your replacement, press Esc, then jump with n and repeat with the dot key.
/hello
cgnBYE
n
.
That dot repeat is worth learning. My Vim keybinds guide collects more of these small repeatable moves that compound over a day of editing.
Jump to the word under your cursor with * and #
Place the cursor on any word and press the asterisk in normal mode to search forward for that exact word, pressing the key again to walk through further matches.
The hash does the same thing toward the top of the file. Both commands match whole words only, so searching on hello never lands on Othello.
This pair is the quickest start to a rename. Search with the asterisk, then run one substitute with an empty search part, and Vim reuses the word you just found.
:%s//BYE/g
To match regardless of case while searching, set one option before you start.
:set ic
Replace with the substitute command
The substitute command, shortened to s, carries the whole job. Its shape is range, then s, then search text, replacement, and flags, each separated by slashes.
:[range]s/search_text/replacement/[flags]
With no range, Vim touches only the current line and only the first match on it, which I confirmed on my scratch file before trusting it.
:s/Hello/HI/
The g flag extends the replacement to every match on the line, and the percent sign extends it to every line in the file, which gives you the command you will type most.
:s/Hello/HI/g
:%s/Hello/HI/g
My test file held three capitalized Hello lines plus one lowercase hello. The second command above replaced the three capitalized ones and left the lowercase line alone, exactly as written.
Leave the replacement empty to delete every match, and leave the search part empty to reuse whatever you last searched for.
:%s/Hello//g
:%s//BYE/g
Aim the replacement with ranges, confirmation, and case flags
Swap the percent sign for line numbers when a whole-file replace is more than you want.
:4,7s/Hello/HI/g
I ran the equivalent on two middle lines of my scratch file and only those lines changed.
| Range | Where Vim works |
|---|---|
| No range | Current line only |
| % | Every line in the file |
| 4,7 | Lines 4 through 7 |
| .,+3 | Current line plus the next three |
| ‘<,’> | The current visual selection |
Add the c flag when a replace feels risky, and Vim stops at every occurrence to wait for your answer.
:%s/Hello/HI/gc
Each prompt accepts seven answers, and I checked every one against the built-in help so you get the exact keys.
| Key | What it does |
|---|---|
| y | Replace this match |
| n | Skip this match |
| a | Replace this and all remaining matches |
| q | Quit, keeping changes made so far |
| l | Replace this match, then quit |
| Esc | Quit without touching this match |
| Ctrl-E / Ctrl-Y | Scroll the screen up or down while deciding |
The i flag ignores case and the I flag enforces it for one command, and the same choice can sit inside the search text as backslash-c or backslash-C.
:%s/hello/BYE/gi
:%s/hello/BYE/gI
Running the first line turned every casing of hello on my scratch file, including the lowercase one, into BYE. That visible difference is why I test case flags instead of guessing them.
Without a guard, a replace also catches words you never meant to touch, like the hell inside hello, so wrap the search text in escaped angle brackets for standalone words only.
:%s/\<hello\>/BYE/g
Act on matching lines with the global command
The global command, shortened to g, runs any normal Ex command on every line that matches. Give it a search text and a command, separated by slashes.
:g/match_text/command
When your file starts with a block of Python imports you want gone, one global delete removes exactly those lines and nothing else.
:g/^import/d
I ran that on a scratch file holding a few import lines among plain text, and only the imports vanished while the rest stayed put.
:g!/import/d
:v/import/d
I verified the second form as well: everything except the two import lines disappeared. Empty lines are another classic target, matched by start-of-line, optional whitespace, and end-of-line.
:g/^\s*$/d
Deleted lines go to the default register, so a mistaken global delete is recoverable. My registers guide shows how Vim stores killed text and how to paste it back.
For the same replace job outside any editor, in a script or a pipeline, reach for the stream editor instead. My sed guide covers file-wide substitution from the shell, and the grep guide helps you preview matches across files before you change them.
Frequently asked questions
These are the questions I hear most once someone learns the substitute command. Each answer uses the commands tested above.
How do I replace all occurrences in a file in Vim?
Use :%s/old_text/new_text/g in normal mode. The percent sign covers every line and the g flag covers every match on each line. Without the g flag, only the first match per line changes.
How do I confirm each replacement in Vim?
Add the c flag, as in :%s/old_text/new_text/gc. Vim stops at every match. Answer y to replace, n to skip, a to replace all remaining, q to quit keeping changes so far, l to replace once and quit, or Esc to quit.
How do I make search and replace case-insensitive in Vim?
Add the i flag, as in :%s/hello/BYE/gi, to ignore case for that command. You can also place \c inside the search text for the same effect, or run :set ic to ignore case for searching in general.
How do I replace only whole words in Vim?
Wrap the search text in escaped angle brackets, as in :%s/\<hello\>/BYE/g. Only standalone hello matches, so words that merely contain those letters stay untouched.
How do I delete all lines matching a word in Vim?
Run :g/word/d in normal mode to delete every line containing the word. Use :v/word/d to delete every line that does not contain it. Deleted lines go to the default register, so you can paste them back if needed.
Pick one file you edit often and replace something you typed yourself today, with confirmation on. When you are done, save and leave the editor cleanly with my guide to exiting Vim. These commands also work unchanged in Neovim, and my Neovim install guide gets you set up on Linux.
