Substitute: :s and ranges

Vim · Practical · 12 min

Search-and-replace across a file is a daily task, and ranges make it precise.

The substitute command is :[range]s/pattern/replacement/[flags].

Without a range it works on the current line only. Common ranges:

  • % the whole file, so :%s/foo/bar/g is the classic replace-all.
  • 10,20 lines 10 to 20, .,$ from here to the end, .,+5 the next five lines.
  • '<,'> the Visual selection (inserted automatically when you press : in Visual mode).
  • /start/,/end/ from the next line matching start to the next matching end.

Common flags:

  • g replaces every match on the line, not just the first.
  • c asks for confirmation at each match (y, n, a for all, q to quit).
  • i / I ignore / respect case regardless of settings.
  • n only counts matches without changing anything: :%s/TODO//gn.

In the replacement, & stands for the whole match and \1...\9 for capture groups \(...\). \r inserts a line break. If the pattern contains slashes, use another delimiter: :s#/usr/bin#/opt/bin#g.

An empty pattern reuses the last search, which gives a great workflow: search with / until the highlight shows exactly what you want, then :%s//new/g. After a substitution, & repeats it on the current line and g& repeats it on the whole file.

Example

:s/foo/bar/          " first foo on this line
:s/foo/bar/g         " every foo on this line
:%s/foo/bar/g        " every foo in the file
:%s/foo/bar/gc       " ...asking at each match
:10,20s/^/# /        " comment out lines 10-20
:%s/\(\w\+\), \(\w\+\)/\2 \1/  " 'Smith, Ann' -> 'Ann Smith'
:%s/TODO//gn         " count TODOs without changing anything
:%s#http://#https://#g  " alternative delimiter

Remember

  • :%s/old/new/g = replace all in file
  • Flags: g all on line, c confirm, n count only
  • Empty pattern reuses the last / search

Watch out for

  • Forgetting g: :%s/a/b/ changes only the first match on each line.

Check yourself

  1. What does `:%s/x/y/` (no flags) do on a line containing `xxx`?
  2. How do you count matches of `TODO` in the file without changing it?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: vimhelp.org/change.txt.html#%3Asubstitute

Substitute: :s and ranges · Vim · Topolearn