Vim's :substitute command, usually shortened to :s, finds text matching a pattern and replaces it. A substitution combines a line range, search pattern, replacement text and optional flags:
:[range]s/{pattern}/{replacement}/[flags]The parts are:
[range]selects the lines to change. Without a range, Vim uses the current line.{pattern}is the Vim regular expression to find.{replacement}is the text used for each match.[flags]control details such as replacing every match, ignoring case or asking for confirmation.
Replace on the current line
Replace the first occurrence of findMe on the current line:
:s/findMe/replaceWith/Add the g flag to replace every occurrence on that line:
:s/findMe/replaceWith/gWithout g, Vim replaces only the first match on each selected line.
Replace throughout the file
The % range selects every line in the current buffer:
:%s/findMe/replaceWith/gTo restrict the substitution to lines 10 through 16:
:10,16s/findMe/replaceWith/gVisual mode can supply the range too. Select the required lines, type :, and Vim inserts the '<,'> range automatically:
:'<,'>s/findMe/replaceWith/gConfirm each replacement
Add the c flag when you want to review each match:
:%s/findMe/replaceWith/gcVim highlights the current match and offers these choices:
| Key | Action |
|---|---|
y |
Replace this match and continue. |
n |
Keep this match and continue. |
a |
Replace this and every remaining match. |
q or Esc |
Stop substituting. |
l |
Replace this match and stop. |
Ctrl+E |
Scroll the window up. |
Ctrl+Y |
Scroll the window down. |
You can undo the completed substitution with u in Normal mode.
Control case sensitivity
The i flag makes this substitution case-insensitive regardless of the current 'ignorecase' setting:
:%s/findMe/replaceWith/giThe uppercase I flag forces case-sensitive matching:
:%s/findMe/replaceWith/gIThese flags affect only the substitution where they are supplied.
Replace text containing slashes
The slash is a delimiter, so it must normally be escaped when it is part of the pattern or replacement:
:%s/\/old\/path/\/new\/path/gVim allows another non-alphanumeric delimiter, which is often easier to read for paths and URLs:
:%s#/old/path#/new/path#gBoth commands perform the same type of substitution.
Remember that the search is a pattern
The search side uses Vim regular-expression syntax. Characters such as ., *, [, ] and \ can have special meanings. Use \V at the start of a pattern when most of the search text should be treated literally:
:%s/\Vold.value/replaceWith/gThe replacement side also has special values. In particular, & inserts the complete matched text. Escape it as \& when the replacement needs a literal ampersand:
:%s/Research/Research \& Development/gQuick reference
| Command | Scope and behaviour |
|---|---|
:s/old/new/ |
First match on the current line. |
:s/old/new/g |
Every match on the current line. |
:%s/old/new/g |
Every match in the current buffer. |
:10,16s/old/new/g |
Every match from lines 10 through 16. |
:%s/old/new/gc |
Every match in the buffer, with confirmation. |
:%s/old/new/gi |
Every match, ignoring case. |
:%s/old/new/gI |
Every match, matching case exactly. |
Vim's built-in help is available without leaving the editor:
:help :substitute
:help :s_flags
:help sub-replace-specialThe same material is maintained in Vim's official change.txt reference.