river
river

Reputation: 734

Ask for explanation of one vim command

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

Answers (3)

Ingo Karkat
Ingo Karkat

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

William Pursell
William Pursell

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

Qeole
Qeole

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

Related Questions