293

I know the regex for doing a global replace,

%s/old/new/g

How do you go about doing an interactive search-replace in Vim?

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
kal
  • 28,545
  • 49
  • 129
  • 149

7 Answers7

536

Add the flag c (in the vim command prompt):

:%s/old/new/gc

will give you a yes/no prompt at each occurrence of 'old'.

"old" is highlighted in the text; at the bottom of the window it says "replace with new (y/n/a/q/l/^E/^y)?)"

Vim's built-in help offers useful info on the options available once substitution with confirmation has been selected. Use:

:h :s

Then scroll to section on confirm options. Screenshot below:

Text that says "[C] Confirm each substitution. [...] CTRL-Y to scroll the screen down"

For instance, to substitute this and all remaining matches, use a.

Laurel
  • 5,965
  • 14
  • 31
  • 57
Mark Biek
  • 146,731
  • 54
  • 156
  • 201
  • 35
    +1, I learned something new today! vim has so many hidden secrets.. :) – Marc Novakowski Feb 03 '09 at 02:45
  • Indeed! I did not know about the c modifier. – strager Feb 03 '09 at 02:59
  • 10
    Learning vim commands is a little bit like playing Nethack. You never know what wonders a single character is going to hold. – Mark Biek Feb 03 '09 at 03:06
  • Well, bugger me ! I've been using vi for nigh on 30 years and this is the first time I've seen this. That little editor continues to amaze me even after all this time (especially the vim extensions). +1 for making my life easier, where were you 20-odd years ago? – paxdiablo Feb 03 '09 at 03:10
  • 3
    @Pax Alternating between building a tree fort and writing BASIC programs to print out dirty words :) – Mark Biek Feb 03 '09 at 03:19
  • 28
    I imagine the "c" is for "confirm" – matpie Feb 03 '09 at 03:31
  • 8
    I'm honestly not trying to come across as snarky, but all of this could have been found by doing ":help :s" which would have led you straight to ":help :s_flags". – Jeremy Cantrell Feb 05 '09 at 16:09
  • 1
    Use the last search pattern with %s//replacement/gc. This allows you to confirm as you are typing the matching text that you'll hit what you want. – Vincent Scheib Jan 26 '12 at 05:55
  • 2
    Or retrieve the text under the cursor using ctrl-r ctrl-w. Something I recently learned here on SO. – johnny Jan 26 '12 at 06:51
  • 15
    @jeremy: that requires knowing that help command exists, and knowing that one needs to type "colon s" switch to get you to the relevant help file. How or where would one learn that? – Dennis Apr 15 '14 at 15:04
  • Worth noting (from the manual): "If the 'gdefault' option is on, this flag is on by default and the [g] argument switches it off." So, if you have "set gdefault" in your .vimrc, use "%s/old/new/c" otherwise only the first occurrence per line will be replaced. – Bruno Belotti Feb 12 '16 at 11:05
  • 1
    Actually @jeremy you are not snarky (whatever that means) and it was extremely useful to me to find out how the help command would have helped. Teach someone to fish and he can feed himself for life. Just a note, on ubuntu you need to do "sudo apt-get install vim-runtime" to get the help command. – mario Nov 23 '16 at 17:25
89

Mark Biek pointed out using:

%s/old/new/gc

for a global search replace with confirmation for each substitution. But, I also enjoy interactively verifying that the old text will match correctly. I first do a search with a regex, then I reuse that pattern:

/old.pattern.to.match
%s//replacement/gc

The s// will use the last search pattern.

Vincent Scheib
  • 17,142
  • 9
  • 61
  • 77
  • 9
    One of the greatest things about using/learning vim is just how deep the rabbit hole goes! – ken Feb 21 '13 at 17:25
  • 2
    Nice, I was always doing the search, then using / to paste the last search into the substitute command. – Atilla Filiz Jul 04 '14 at 08:23
  • Exactly what I miss from Sublime Text! – Xenofex Aug 30 '16 at 02:50
  • This answer is particularly useful, as I imagine a lot of times you decide to replace instances of a word, it's the word you just searched for. – M_M Feb 11 '20 at 10:33
20

I think you're looking for c, eg s/abc/123/gc, this will cause VIM to confirm the replacements. See :help :substitute for more information.

Logan Capaldo
  • 39,555
  • 5
  • 63
  • 78
9

I usually use the find/substitute/next/repeat command :-)

/old<CR>3snew<ESC>n.n.n.n.n.n.n.

That's find "old", substitute 3 characters for "new", find next, repeat substitute, and so on.

It's a pain for massive substitutions but it lets you selectively ignore some occurrences of old (by just pressing n again to find the next one instead of . to repeat a substitution).

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • I use this as well, even for similar texts. (3cW...) – strager Feb 03 '09 at 03:00
  • 1
    It's not an antipattern! It's sweet. And you can search in the opposite direction using N. Really good if you see a word and want to change it. *cwNewTextN.n.n. (This will jump away from the word under the cursor, but then jump back soon as you have changed the next occurrence. – PEZ Feb 03 '09 at 07:57
  • what is `` ? – makansij Jun 10 '17 at 04:59
  • 1
    @makansij: better late than never! is a carriage return, which would perform the search action. So actually the suggestion is to: (1) search for the pattern first; (2) enter a command to change/edit the first match found; (3) repeat the last search; (4) repeat the last editing command; (5) continue ad nauseam. When I first saw it described this way, it also confused me – Luis Jun 16 '22 at 20:52
9

If you just want to count the number of occurrences of 'abc' then you can do %s/abc//gn. This doesn't replace anything but just reports the number of occurrences of 'abc'.

OmarOthman
  • 1,718
  • 2
  • 19
  • 36
Amjith
  • 22,626
  • 14
  • 43
  • 38
3

If your replacement text needs to change for each matched occurrence (i.e. not simply choosing Yes/No to apply a singular replacement) you can use a Vim plugin I made called interactive-replace.

hwrod
  • 461
  • 4
  • 6
2

Neovim now has a feature inccommand which allows you to preview the substitution:

inccommand has two options:

  • set inccommand=split previews substitutions in a split pane
  • set inccommand=nosplit previews substitution in the active buffer

enter image description here

Image taken from: https://medium.com/@eric.burel/stop-using-open-source-5cb19baca44d Documentation of the feature: https://neovim.io/doc/user/options.html#'inccommand'

OldBuildingAndLoan
  • 2,801
  • 4
  • 32
  • 40
sumek
  • 26,495
  • 13
  • 56
  • 75