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 documents/<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
let a = ['', '1']
define an variablea
to hold our array%s/.../.../
do a substitution on every line in the file%s/bar\zs/.../
do a substitution on bar but start the replacement after bar using\zs
\=
inside the replacement portion of the:s
command uses the value of the following expressionreverse(a)
reverse simply reverses the array, but does so in-placereverse(a)[0]
reverse returns the now reversed array so get the first element/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
What Does the Line '!/Bin/Sh -E' Do
.Bashrc Syntax Error: Unexpected End of File
How to Get Environment Variables of Remote Host
How to Copy a File with '$' in Name in Linux
How to Execute Multiple Commands After Sudo Command
If Adding a Command That Repeats Every 10 Minutes to Crontab, When Does the First Job Run
Ubuntu: Wait for Network Link Up and Execute a Bash Command
Combine Results of Column One Then Sum Column 2 to List Total for Each Entry in Column One
How to Count Most Occuring Sequence of 3 Letters Within a Word with a Bash Script
How to Export a Modified Kernel Header
How to Compare 2 Lists of Ranges in Bash
Erge Text Files Ordered by Numerical Filenames in Bash