Reputation: 734
let i=1 | g/aaa\zs/s//\=i/ | let i=i+1
The above command add counter number after matched pattern. So the following text is changed.
aaab
aaab
aaab
to
aaa1b
aaa2b
aaa3b
'|' joints commands into one command. In my opinion, the commands are executed sequentially like firstly let i=1, then g/aaa\zs/s//\=i/ , finally let i=i+1 . From the result above, s//\=i/**and **let i=i+1 are executed by g command. Can anyone explain? The following command does wrong work. But I don't know why.
let i=1 | g/aaa\zs/s//\=i | let i=i+1
Upvotes: 2
Views: 107
Reputation: 172510
Usually, the |
separates two Ex commands, and they are then indeed executed sequentially. But some commands take a |
as part of their arguments. :global
is one of them (full list at :help :bar
). So, the special application of commands over matching lines is applied with both the :s
and the :let
commands (the latter of which can be shortened as :let i+=1
BTW).
Upvotes: 0
Reputation: 212198
In s//\=i/
, the replacement string is terminated and the |
is treated as an argument by global. However, when you remove the trailing /
, the replacement string to s
consumes the | let i=i+1
. From the help doc for sub-replace-special
, you can find: "When the substitute string starts with "\=" the remainder is interpreted as an expression." So the expression i | let i=i+1
is evaluated, but the increment is not available outside of that evaluation.
Upvotes: 1
Reputation: 9114
You should understand your first command as:
let i=1 | g/aaa\zs/ ( s//\=i/ | let i=i+1 )
(Parenthesis are only here for explaining, they'd cause syntax error if typed).
i.e. everything after the g/<pattern/
is a single command given as an argument to the global g
command.
So indeed: we start with let i=1
, then for all lines matching pattern aaa
we execute: s//\=i/ | let i=i+1
(substitution, then incrementing i
).
Your second command does not work because s
does not function the same way as g
, and it does need an ending /
after the expression to substitute to pattern.
Upvotes: 1