18

Frequently when I am doing a find and replace in vi I will do it like this:

:%s/find/replace/gc

This gives you the option to skip by pressing n, or replace by pressing y. But, sometimes I will accidentally skip over one in a large file by pressing n when I meant to press y.

How do I go backwards to the previous one and give me a second change?

Essentially, how to I find (search) the other direction temporarily? thanks.

makansij
  • 9,303
  • 37
  • 105
  • 183

3 Answers3

10

I'm not sure if you would like to interrupt current find-replace operation and resume it again. But if that is acceptable, here is my suggestion:

  1. Start your find-replace the way you mentioned: :%s/find/replace/gc
  2. After you accidentally skip over a substitution by pressing n, interrupt the search by pressing <ctrl-C>
  3. Press <shift-N> to go back to the previous occurrence of your find term
  4. Run find-replace a little differently while you are at this word: :.,$s/find/replace/gc
  5. Continue the operation

All this functionality works with vim native capabilities without having to install any addon.

Note: The .,$ range specifier indicates to perform :s (substitute) operation over a range of lines that start with current line (indicated by .) and until last line (indicated by $).

Note2: It might be known to you, but reiterating for anyone else who stumbles upon this post searching for something similar - The % range specifier indicates to perform :s (substitute) operation over all lines of currently active buffer.

Prasanna
  • 1,184
  • 8
  • 12
  • Shocked that this is not supported, but if you must edit your previous search, you may find `q:` helpful. Documented in `:h cmdline-window`. – young_souvlaki Jun 21 '22 at 20:40
2

This is not answer to the question, but a very good alternative. I recently discovered the CtrlSF plugin and it improves the search /replace process dramatically.

Basically, you have the search results in a buffer and you can do all the replacements in this single buffer.

In your scenario, you first do :CtrlSF find, get a buffer with all the matches in all files and then you do /find and move with n over your targets and change them (of course, you can actually change only the first one and then repeat the replacement with .).

If you miss some target, you just hit N to go back to the previous result and replace it.

Borys Serebrov
  • 15,636
  • 2
  • 38
  • 54
1

Seems like you can't back to previous match using this pattern. Appeared bar propose following commands y/n/a/q/l/^E/^Y but no one of them will return backward to previous match.

But you can use little different pattern described bellow:

  • Type this /pattern replacing pattern with interested word;
  • Your cursor is navigated to first occurrence, if you don't need to change it press n it will navigates you to the next occurrence;
  • Since you understand you need to replace a word, do this by typing cw, this command cuts the forward word and turns you to insertion mode;
  • Type in desired text on the released place and press ESC to switch back to command mode;
  • Now again press n until desired occurrence;
  • Since you realize that you need to change an occurrence, just press on . it will repeat previously mentioned actions;
  • If you want to go back just use N.
Purkhalo Alex
  • 3,309
  • 29
  • 27