Say I have the following file
<block>
<foo val="bar"/>
<foo val="bar"/>
</block>
<block>
<foo val="bar"/>
<foo val="bar"/>
</block>
How could I make that into
<block>
<foo val="bar1"/>
<foo val="bar"/>
</block>
<block>
<foo val="bar1"/>
<foo val="bar"/>
</block>
One thing I tried to do was record a macro with :%s/bar/bar1/gc
and press y
and n
once each and then try to edit that macro. For some reason I cannot edit the macro. :(
When you want to search for a string of text and replace it with another string of text, you can use the syntax :[range]s/search/replace/. The range is optional; if you just run :s/search/replace/, it will search only the current line and match only the first occurrence of a term.
Change and repeat Search for text using / or for a word using * . In normal mode, type cgn (change the next search hit) then immediately type the replacement. Press Esc to finish. From normal mode, search for the next occurrence that you want to replace ( n ) and press . to repeat the last change.
You can now edit the search pattern and press Enter. Use Ctrl-r Ctrl-w for a <cword>, or Ctrl-r Ctrl-a for a <cWORD>. After searching, press Ctrl-o to jump back to your previous position (then Ctrl-i will jump forwards). After searching, an empty search pattern will repeat the last search.
Just to show that this can be done in a substitution:
:let a = ['', '1']
:%s/bar\zs/\=reverse(a)[0]/g
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.
let a = ['', '1']
define an variable a
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):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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With