How to add line numbers to range of lines in Vim?
Asked Answered
S

8

80

How can I add line numbers to a range of lines in a file opened in Vim? Not as in :set nu—this just displays line numbers—but actually have them be prepended to each line in the file?

Skipper answered 31/10, 2008 at 7:5 Comment(1)
This question should apply to any file that has end-of-line markers, not just source code files.Franchot
L
129

With

:%s/^/\=line('.')/

EDIT: to sum up the comments.

This command can be tweaked as much as you want.


Let's say you want to add numbers in front of lines from a visual selection (V + move), and you want the numbering to start at 42.

:'<,'>s/^/\=(line('.')-line("'<")+42)/

If you want to add a string between the number and the old text from the line, just concatenate (with . in VimL) it to the number-expression:

:'<,'>s/^/\=(line('.')-line("'<")+42).' --> '/

If you need this to sort as text, you may want to zero pad the results, which can be done using printf for 0001, 0002 ... instead of 1, 2... eg:

:%s/^/\=printf('%04d', line('.'))/

Anyway, if you want more information, just open vim help: :h :s and follow the links (|subreplace-special|, ..., |submatch()|)

Leges answered 31/10, 2008 at 10:18 Comment(8)
Tried doing this on a visual selection (where 1 would be the first line in selection) however it starts number at that line numeber in the file. Any way to modify the start number? Thanks!Indaba
@Indaba offset can be 1-line("'<"). Wondering, why such old question appeared in my RSS.Gouveia
I guess it's because of this new response: https://mcmap.net/q/247413/-how-to-add-line-numbers-to-range-of-lines-in-vim/…Leges
You can try: - the documentation (:help :s here), vim tips (vim.wikia.com), plugins written by others, vim_use (the official mailing list) and forums like this one.Leges
I can't find =line on the help. I'm wondering what other commands you can use as replacements in a substitution.Virilism
Follow the links from :h :s -> subreplace-specialLeges
just in case anyone else needs to know, to add a string after the number do :%s/^/\=line('.') . 'string'/. in my case i needed a comma since i was numbering rows in a csv file, so i did :%s/^/\=line('.') . ','/Socha
In addition to visual mode, you can manually specify the range, eg. 2,11s/^/\=line('.')/Echols
W
40

cat -n adds line numbers to its input. You can pipe the current file to cat -n and replace the current buffer with what it prints to stdout. Fortunately this convoluted solution is less than 10 characters in Vim:

:%!cat -n

Or, if you want just a subselection, visually select the area and type this:

:!cat -n

That will automatically put the visual selection markers in, and will look like this after you've typed it:

:'<,'>!cat -n

In order to erase the line numbers, I recommend using Ctrl+v, which will allow you to visually select a rectangle. You can then delete that rectangle with x.

Whaling answered 31/10, 2008 at 7:10 Comment(3)
What if u want the line numbers start with 0 instead of 1?Klemens
Delete first line, number the rest. Readd first line afterwards with a leading '0'. ;)Tsimshian
Note that cat -n puts five spaces before the number and a tab after the number. My cat is from GNU coreutils 9.1.Lining
P
27

On a GNU system: with the external nl binary:

:%!nl
Palpitant answered 31/10, 2008 at 7:12 Comment(2)
cool nl -v allows you to specify where the numbering should start, so if you want the first line to be line 0 instead of 1 use nl -v 0Klemens
Prepend each visually selected line with "1.", "2.", "3.", etc. using :'<,'>!nl -w1 -s'. 'Lining
D
7

With Unix-like environment, you can use cat or awk to generate a line number easily, because vim has a friendly interface with shell, so everything work in vim as well as it does in shell.
From Vim Tip28:

:%!cat -n

or

:%!awk '{print NR,$0}'

But, if you use vim in MS-DOS, of win9x, win2000, you loss these toolkit. here is a very simple way to archive this only by vim:

fu! LineIt()
  exe ":s/^/".line(".")."/"
endf

Or, a sequence composed with alphabet is as easy as above:

exe "s/^/".nr2char(line("."))."/" 

You can also use a subst:

:g/^/exe ":s/^/".line(".")."^I/"

You can also only want to print the lines without adding them to the file:

"Sometimes it could be useful especially be editing large source files to print the line numbers out on paper.
To do so you can use the option :set printoptions=number:y to activate and :set printoptions=number:n to deactivate this feature.
If the line number should be printed always, place the line set printoptions=number:y in the vimrc."

Drescher answered 31/10, 2008 at 7:12 Comment(8)
Did you mean 'cat' instead of 'call' in the first example?Libbi
@Lance: two years later, I am not really sure: revision 3 of this post shows me reverting a correction from cat to call... (source being probably Vim tip28 as in neuron.tuke.sk/~hudecm/VimTips-OFFLINE-nov02.txt)Drescher
OK, the awk line was what I needed anyway. Do you know how I would implement that so that it gave me 3 or 4 letter numbers, like starting with 100 or 1000?Libbi
Following the references make it seem like it should be cat. I found the awk statement to give me more digits: :%!awk '{print 1000+NR*10,$0}'. The only problem now (which isn't much of one) is that my stripping statement :%s/^[0-9]*// leaves extra spaces on the front and referencing \s doesn't seem to help.Libbi
@Lance: ok, I have edited the answer accordingly. Your specific problem can be an answer of its own in this page;)Drescher
I've put line numbers with: :%!cat -n but how can they be removed?Rayerayfield
@Rayerayfield Not sure: You should ask that as a separate question (with a link to this answer as context)Drescher
@Drescher thanks for your suggestion. I have asked a new question here: #36580220Rayerayfield
L
4

First, you can remove the existing line numbers if you need to:

:%s/^[0-9]*//

Then, you can add line numbers. NR refers to the current line number starting at one, so you can do some math on it to get the numbering you want. The following command gives you four digit line numbers:

:%!awk '{print 1000+NR*10,$0}'
Libbi answered 12/1, 2011 at 22:10 Comment(0)
M
3

The "VisIncr" plugin is good for inserting columns of incrementing numbers in general (or letters, dates, roman numerals etc.). You can control the number format, padding, and so on. So insert a "1" in front of every line (via :s or :g or visual-block insert), highlight that column in visual-block mode, and run one of the commands from the plugin.

Morale answered 2/11, 2008 at 0:9 Comment(0)
L
3

The best reply is done in a duplicate question.

In summary:
with CTRL-V then G I 0 You can insert a column of zero.

Then reselect your last selection, the whole column, with gv and increment:
gv g CTRL-A

See also: https://vim.fandom.com/wiki/Making_a_list_of_numbers#Incrementing_selected_numbers

Lumpfish answered 4/7, 2022 at 8:52 Comment(0)
P
1

If someone wants to put a tab (or some spaces) after inserting the line numbers using the this excellent answer, here's a way. After going into the escape mode, do:

:%s/^/\=line('.').'    '/

^ means beginning of a line and %s is the directive for substitution. So, we say that put a line number at the beginning of each line and add 4 spaces to it and then put whatever was the contents of the line before the substitution, and do this for all lines in the file.

This will automatically substitute it. Alternatively, if you want the command to ask for confirmation from you, then do:

:%s/^/\=line('.').'    '/igc

P.S: power of vim :)

Pelite answered 8/9, 2018 at 10:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.