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. :(
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