11

usually I deal with files that look like this:

0.98   3.45
2.45   3.90
.
.
.
4.56   8.45

lets say with 100 lines. I would like to get something like this:

1   0.98   3.45
2   2.45   3.90
.
.
.
100 4.56   8.45

with a first column of integers. What I usually do is to generate a column file with just the numbers 1,2...100 and then select that block and paste it into the file with two columns. As the number of rows is almost always different my approach seems to be very slow.

Do you have any suggestions?

Thanks.

armando
  • 1,360
  • 2
  • 13
  • 30
  • Duplicate question: http://stackoverflow.com/questions/252766/add-line-numbers-in-vim – Edward Aug 13 '13 at 22:01
  • @Edward These answers don't speak about alignment, though. – mhinz Aug 13 '13 at 22:20
  • 1
    @mhinz Actually, the question doesn't mention alignment, and the example is not aligned. (Plus I was typing while you were and so didn't see your answer.) But if I was doing it, I would want the numbers right-aligned too, so I'm glad you've shown me something I didn't know. Cheers. – Edward Aug 13 '13 at 23:07
  • use `cat`: `:%!cat -n` – ernix Aug 14 '13 at 01:20
  • @Edward Sorry for nit-picking here, but the second column of the example output actually is aligned. :) – mhinz Aug 14 '13 at 07:37
  • @mhinz Oh, I see what you mean now. My bad. I had thought you meant the right-justification of the line-numbers themselves. Carry on. ;) – Edward Aug 14 '13 at 15:40
  • It doesn't suit the OP's question but for other circumstances `:put =range(1,15)` for example, is great. – NeilG Feb 22 '20 at 14:05

5 Answers5

16
:%s/^/\=printf('%-3d ', line('.'))

More information:

:help :s\= 
:help printf()
:help line()
mhinz
  • 3,291
  • 20
  • 20
9

Here's an alternative vim-only Normal mode version. With your cursor in the first column, on the first row:

<C-v>GI0 <ESC>gvg<C-a>
  • <C-v> visual block mode (:help visual-block)
  • G is select to the bottom of the screen (:help G)
  • I starts insert mode on line 1 (:help v_b_I)
  • 0 enter a literal zero and a literal space
  • <ESC> go back to normal mode
  • gv reselect the last visual selection (all of column 1) (:help gv)
  • g<C-a> increment sequentially all numbers in the selection (:help v_g_CTRL-A)

Turns this

0.98   3.45
2.45   3.90
4.56   8.45

into this

1 0.98   3.45
2 2.45   3.90
3 4.56   8.45
Parker Tailor
  • 1,290
  • 13
  • 12
4

I find VisIncr invaluable for similar operations (here's the GitHub version for those who use Vundle or NeoBundle). The plugin "facilitates making a column of increasing or decreasing numbers, dates, or daynames". An example of adding line numbers follows:

Select the first column of the file in visual block mode:

gg<C-v>G

Insert a starting number (1 in this case) and a column separator (I'm assuming Tab here):

I1<Tab><Esc>

Reselect the first column of the file:

gv

Run a VisIncr command to increase the numbers:

:I<CR>

You could right-justify the numbers instead with a different command:

:II<CR>

Incrementing dates, letters, hex, and roman numbers is just as easy.

Serge Belov
  • 5,633
  • 1
  • 31
  • 40
3
:%!cat -n

is a quick solution. Followed by

:%s/^\s*//g

it gives you what you want pretty quickly.

romainl
  • 186,200
  • 21
  • 280
  • 313
  • if use external command/tool. `nl` would be better than `cat -n` it provides format options – Kent Aug 14 '13 at 08:00
  • @Kent, you are perfectly right. However, we don't even know if the OP has access to `cat` or `nl` so neither one nor the other may be useful to him. – romainl Aug 14 '13 at 08:02
2

For generating a column of sequential number, nl is your friend. Suppose you want to generate from 1 to n:

  1. Create a file with n lines in vim.

  2. Run :%!nl.

Now you can use <C-v> to select the column of numbers and copy them elsewhere.

Cyker
  • 9,946
  • 8
  • 65
  • 93