How to Replace Finding Words with the Different in Each Occurrence in Vi/Vim Editor

How to replace finding words with the different in each occurrence in VI/VIM editor ?

Replaces each occurence of 10 with replace{index_of_match}:

:let @a=1 | %s/10/\='replace'.(@a+setreg('a',@a+1))/g

Replaces each occurence of 10 with a word from a predefined array:

:let b = ['foo', 'bar', 'vim'] | %s/10/\=(remove(b, 0))/g

Replaces each occurence of 10 with a word from a predefined array, and the index of the match:

:let @a=1 | let b = ['foo', 'bar', 'vim'] | %s/10/\=(b[@a-1]).(@a+setreg('a',@a+1))/g

But since you have to type in any word anyway, the benefit of the second and third function this is minimal. See the answer from SpoonMeiser for the "manual" solution.

Update: As wished, the explanation for the regex part in the second example:

%= on every line in the document

s/<search>/<replace>/g = s means do a search & replace, g means replace every occurence.

\= interprets the following as code.

remove(b, 0) removes the element at index 0 of the list b and returns it.

so for the first occurrence. the line will be %s/10/foo/g the second time, the list is now only ['bar', 'vim'] so the line will be %s/10/bar/g and so on

Note: This is a quick draft, and unlikely the best & cleanest way to achieve it, if somebody wants to improve it, feel free to add a comment

Find and replace strings in vim on multiple lines

The :&& command repeats the last substitution with the same flags. You can supply the additional range(s) to it (and concatenate as many as you like):

:6,10s/<search_string>/<replace_string>/g | 14,18&&

If you have many ranges though, I'd rather use a loop:

:for range in split('6,10 14,18')| exe range 's/<search_string>/<replace_string>/g' | endfor

VIM: Finding and replacing first N occurrences of a word

Using a disposable recording allows you to control exactly how many changes you do:

qq             " start recording in register q
/foo<CR> " search for next foo
cgnbar<Esc> " change it to bar
q " end recording
11@q " play recording 11 times

See :help recording and :help gn.

Another way, using :normal:

:norm! /foo<C-v><CR>cgnbar<C-v><Esc>     <-- should look like this: :norm! /foo^Mcgnbar^[
11@:

See :help :normal and :help @:.

Or simply:

:/foo/|s//bar<CR>
11@:

How to replace all word containing a pattern in vim?

You can use the substitution command like this:

:%s/before/after/g

where

  • %s is the substitution
  • before is the string to match
  • after is the replacement
  • g is the global flag (to replace all occurrences)

If you are matching substrings, you can use

:%s/\<\w*substr\w*\>/newword/g

where

  • \< matches the word boundary
  • \w* matches a word character (0 or more)
  • substr is your substring
  • > matches the word boundary end
  • newword is the new word to replace
  • g is the global replace

In Vim how can I search and replace every other match?

Just to show that this can be done in a substitution:

:let a = ['', '1']
:%s/bar\zs/\=reverse(a)[0]/g

Overview

Replace at the end of every bar with the first element of array in variable a after the array is reversed in-place upon every substitution.

Glory of Details

  1. let a = ['', '1'] define an variable a to hold our array
  2. %s/.../.../ do a substitution on every line in the file
  3. %s/bar\zs/.../ do a substitution on bar but start the replacement after bar using \zs
  4. \= inside the replacement portion of the :s command uses the value of the following expression
  5. reverse(a) reverse simply reverses the array, but does so in-place
  6. reverse(a)[0] reverse returns the now reversed array so get the first element
  7. /g replace all occurances in the line (optional)

General Case

:let a = ['a', 'b', 'c']
:%s/bar\zs/\=add(a, remove(a, 0))[-1]/g

The general case "rotates" the array, a, in-place and uses the last position of the array as the value for the replacement of the substitution.

For more help see

:h :s
:h range
:h /\zs
:h :s\=
:h reverse(
:h :s_flags
:h Lists
:h add(
:h remove

In Vim, replace all occurrences of current term under cursor

You can use:

:%s/<c-r><c-w>/new value/g

where <c-r><c-w> means to literally type CTRL-rCTRL-w to insert the word under the cursor.

Find and replace whole words in vim

You can use \< to match the beginning of a word and \> to match the end:

%s/\<word\>/newword/g


Related Topics



Leave a reply



Submit