vi - how to generate a number sequence?

和自甴很熟 提交于 2019-11-28 03:23:29

Select several lines with V(Shift-v), then type command bellow:

:let i=1 | '<,'>g/^/ s//\=i . " "/ | let i+=2

Type :help sub-replace-expression to read more.

Instead of a complicated construct you could simply use a macro with the CTRL-a function to increment a leading number. Example data:

aaa
bbb
ccc

first insert a start number and a space:

1 aaa
bbb
ccc

then record this macro on line 1 (<C-a> means press CTRL-a):

qq0yf 0j0P0<C-a>q

Explanation:

  1. qq: record macro into register q
  2. 0: go to first column.
  3. yf: yank all until and including the first space (remember your first line has 1 and a space).
  4. 0jP: go down and paste the pattern at the start of the line.
  5. 0<C-a>: go to first column and increment number by one.
  6. q: end macro recording.

this gives:

1 aaa
2 bbb
ccc

now you can apply this macro using @q as long as you want. If you need an increase of two just use CTRL-aCTRL-a instead of just once. Now you could apply this macro to consecutive lines, for example:

:.,$norm @q

will add leading line numbers for the rest of your file.

With Vim 8.0 one can use g Ctrl-a, see :help v_g_CTRL-A

Go to line #4, use Ctrl-v to blockwise select the first character, press Shift i, enter 1 (this is 1, followed by Space) and Esc to exit insert mode. Result will look like this:

this is line #1
this is line #2
this is line #3
1 this is line #4
1 this is line #5
1 this is line #6
1 this is line #7
1 this is line #8
this is line #9
this is line #10

Now, starting from line #5, use Ctrl-v again to select all inserted 1 except the first one. Press g Ctrl-a to create a sequence.

this is line #1
this is line #2
this is line #3
1 this is line #4
2 this is line #5                                                                     
3 this is line #6
4 this is line #7
5 this is line #8
this is line #9
this is line #1

Use 2g Ctrl-a to use a step count of 2.


Inspired by user soulthym: You can save a few key strokes by starting the visual selection in line #8. Select the first character, insert the 1, press gv to reapply the former visual selection, press j to omit the first 1 and press g Ctrl-a to create a sequence.

:4,8s/^/\=line(".")-3." "    

will do what you want

if you need count=2:

:4,8s/^/\=2*(line(".")-3)." " 

this will give you 2,4,6,8,10

line numbers are hard coded in my example, you could use V to select those lines you want to change.

Select the target lines in Visual mode, then run the Ex command

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

Here's a dirty trick but then life is composed of these. :)

ESC :r! for i in $(seq 1 10); do echo "This is line \#${i}"; done

Not cross platform.

I think all the proposed solutions are too difficult to remember, you can use it once but then you need to go into all details every time you use it (if you use it less than once a day or so).

I found the visual incrementing script really easy to install and use. Once it is installed in vim, you just need to generate a column of 0's, select it with Ctrl-V and write the command :I. It will then automatically generate increasing numbers on each line. There are also other features:

  • start with a number different from 0
  • left or right pad numbers with 0's (like 001, ..., 015)
  • decreasing or increasing numbers
  • increase by more than 1
  • dates (but you need an additional plugin), letters of the alphabet, daynames

This solves a more general problem because it works also at a position different from column 0, the column has just to be selectable with Ctrl-V.

The vimball of the plugin is here or here.

dahu

The Nexus plugin provides the Series type and an object, s1, of that type used like this:

:4,8s/^/\=s1.next().' '/

Nexus also comes with an s0 Series object that yields 0 as its first .next() result. Both s0 and s1 use a 1-step increment. All Series objects have a .reset() method which sets them back to their initiated value. New Series objects can be created like the following call:

let s2 = Series(0, 2)

which creates a 2-step object meeting your second request(yielding: 2, 4, 6, 8...)

(if your vim has Perl support -- default in many Linux Distributions): Select the lines in visual mode (V) and do

:perldo s/^/++$z . " "/e

A less flexible, but an easy to remember method is to use a renumbering plugin like Renumber.vim http://www.vim.org/scripts/script.php?script_id=189

If there aren't any numbers yet, like in the OP, some number should be inserted in their place. Renumber can handle the actual ordering and it does it based on just the first number.

In this example I'm using <C-v> to insert the starting number on all the lines you want numbered.

4G<C-v>4jGI1 <Esc>gv:Renumber

To use steps of two

:Renumber s2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!