I am trying Vim capabilities and stuck with this task - addition the incrementing number to the end of each line.

Testing lines:


This command works partially:

:let n=1 | g/text/s/$/\=n/ | let n+=1



But I want to have space between the added numbers and the 'text'.

The adding of space ' ' before the \=doesn't work, because the \= should be in the beginning of substitute expression, else it is not parsed as an expression, but inserted literally - text =n:

:let n=1 | g/text/s/$/ \=n/ | let n+=1 ### doesn't work as expected

So, the questions:

  1. Is it possible to insert a string in the substitute expression?

Like this (the n is the variable):


or this:

  1. Can I use multiple variables in the substitute expression by separating them from each other like in the bash?



3. Do you know more suitable/simple way for solving this task?

  • Does your buffer contain lines other than text? And do the text lines start on line 0? – James Jan 17 '19 at 19:31
  • @DJMcMayhem No, the buffer can contains any characters, the Python source code, for example. Also, this action can be required in the any line number. – MiniMax Jan 17 '19 at 20:04

For your answer specifically, you could get around this by concatenating a space with the number, i.e.

:let n=1 | g/text/s/$/\=" ".n/ | let n+=1

If you want to do this to every line, there are some much shorter ways to do this. For example:

:%s/$/\=" ".line('.')

Or if you only want to number the lines matching "text", then either of these:

:%s/text/\=submatch(0)." ".line('.')
:%s/text\zs/\=" ".line('.')

You could even do the entire thing in normal mode. For example, you could do this:

gg<C-v>G$A 0<esc>gvg<C-a>

Where <C-v> means ctrl-v and <C-a> means ctrl-a

| improve this answer | |
  • Thanks, it works. I was trying concatenation, but either without quotes, like s/$/\= .num/ or with quotes, but without dot: s/$/\=' 'n/ :). No, the line number can be random, as well as its content. The 'text' string were picked just for example. – MiniMax Jan 17 '19 at 20:06
  • The second solution should be :%s/$/\=" ".line('.'), otherwise it replaces the text part to the line number, that is not what I want. Also, it numbers all lines in the buffer, empty lines included. – MiniMax Jan 17 '19 at 20:15
  • @MiniMax Yes, good catch. I know that will do it to every line, but that was before I realized you only wanted specific lines. I'll leave that part up in case it can help someone else, but I'll edit it to be more clear about what it's doing. – James Jan 17 '19 at 20:20
  • 1
    The third one is beautiful. I knew about incrementing number by Ctrl-a, but didn't know g CTRL-A. It will be good to add description for gv and g CTRL-A to the answer for future. Note for others: the information about them located in the :h gv and :h Ctrl-a. – MiniMax Jan 17 '19 at 20:40

Answer to the question №1:

:let n=1 | g/text/s/$/\=printf(" %d", n)/ | let n+=1


text 1 
text 2 
text 3 
text 4 
text 5 

Answer to the question №2:

The substitute expression can contain multiple variables separated (concatenated) by dot . operator.

:let a = 'one'
:let b = 'two'
:let c = 'three'



If it is needed separate them by space, then do:

:g/text/s/$/\=' '.a.' '.b.' '.c/


:g/text/s/$/\=printf(' %s %s %s', a, b, c)/


text one two three 
text one two three 
text one two three 
text one two three 
text one two three 
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.