67

有没有办法在 vi 或 Vim 中生成数字序列?

例如,对于在 Vim 中打开的文件中任意范围的i  到 j行(其中i  <  j),有没有办法从第 i行的数字 1一直到数字(j  - <em >i + 1) 在第 j行?

说,我在文件中有以下几行:

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

我想在第 4 行到第 8 行的数字序列前面加上数字 1 到 5。操作后,生成的文件应如下所示:

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 #10

如果这是可能的,有没有办法为生成的序列使用不同的步长?例如,是否可以将 2 用作步长,以便生成的序列为 2、4、6、8 等?

注意:问题“<a href="https://stackoverflow.com/questions/252766/add-line-numbers-in-vim">如何将行号添加到 Vim 中的行范围?” 提出了类似的问题,但并不相同。

4

10 回答 10

97

Vim 7.4.754开始可以使用g Ctrl-a,请参阅:help v_g_CTRL-A

转到第 4 行,使用Ctrl-v逐块选择第一个字符,向下 4 行,按Shift i,输入0 (这是0,后跟Space)并Esc退出插入模式。

现在使用gv重新选择之前选择的区域。按下g Ctrl-a以创建序列。

我从0这里开始,所以我可以重新选择gv。如果以 a 开头1,则需要手动重新选择,同时省略第一个1

用于2g Ctrl-a使用步数 2。


演示如何生成数字序列的屏幕截图

于 2018-01-23T17:55:44.873 回答
61

使用 (Shift-v) 选择几行V,然后键入以下命令:

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

键入:help sub-replace-expression以阅读更多信息。

于 2012-03-28T08:29:32.887 回答
31

您可以简单地使用带有CTRL-a函数的宏来增加前导数字,而不是复杂的构造。示例数据:

aaa
bbb
ccc

首先插入一个起始编号和一个空格

1 aaa
bbb
ccc

然后在第 1 行记录此宏(<C-a>表示按下CTRL-a):

qq0yf 0j0P0<C-a>q

解释:

  1. qq: 将宏记录到寄存器中q
  2. 0: 转到第一列。
  3. yf: 猛拉所有直到并包括第一个空格(记住你的第一行有1一个空格)。
  4. 0jP:往下走,将图案粘贴到行首。
  5. 0<C-a>:转到第一列并将数字加一。
  6. q: 结束宏录制。

这给出了:

1 aaa
2 bbb
ccc

现在您可以根据需要应用此宏@q。如果您需要增加两个,只需使用CTRL-aCTRL-a而不是只使用一次。现在您可以将此宏应用于连续的行,例如:

:.,$norm @q

将为文件的其余部分添加前导行号。

于 2012-03-28T08:32:39.247 回答
11
:4,8s/^/\=line(".")-3." "    

会做你想做的

如果您需要计数 = 2:

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

这会给你 2,4,6,8,10

在我的示例中,行号是硬编码的,您可以使用 V 来选择要更改的那些行。

于 2012-03-28T08:36:29.040 回答
5

这是一个肮脏的把戏,但生活就是由这些组成的。:)

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

不跨平台。

于 2012-03-28T08:29:36.013 回答
2

在可视模式下选择目标行,然后运行 ​​Ex 命令

:'<,'>s/^/\=(line('.')-line("'<")+1).' '
于 2012-03-28T08:28:07.653 回答
2

我认为所有提出的解决方案都很难记住,您可以使用一次,但每次使用时都需要深入了解所有细节(如果您每天使用的次数少于一次)。

我发现视觉递增脚本非常易于安装和使用。一旦它安装在 vim 中,你只需要生成一列 0,使用 Ctrl-V 选择它并编写命令:I。然后它将自动在每一行上生成越来越多的数字。还有其他特点:

  • 以不同于 0 的数字开头
  • 用 0 向左或右填充数字(如 001、...、015)
  • 减少或增加数字
  • 增加超过 1
  • 日期(但你需要一个额外的插件),字母,日期名称

这解决了一个更普遍的问题,因为它也可以在与第 0 列不同的位置工作,该列必须可以使用 Ctrl-V 来选择。

插件的 vimball 在这里这里

于 2014-01-15T13:47:59.600 回答
1

Nexus插件提供了 Series 类型和一个对象,该s1类型的使用如下:

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

Nexus 还带有一个s0Series 对象,它的第一个.next()结果是 0。两者都s0使用s11 步增量。所有 Series 对象都有一个.reset()方法可以将它们设置回初始值。可以像以下调用一样创建新的 Series 对象:

let s2 = Series(0, 2)

这将创建一个满足您的第二个请求的两步对象(产生:2、4、6、8 等)。

于 2012-03-28T11:31:20.630 回答
1

(如果你的 vim 有 Perl 支持——许多 Linux 发行版中的默认值):选择可视模式 (V) 中的行并执行

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

或者

:4,8 perldo s/^/++$z . " "/e
于 2018-01-23T12:41:33.127 回答
-1

一个不太灵活但容易记住的方法是使用像 Renumber.vim http://www.vim.org/scripts/script.php?script_id=189这样的重新编号插件

如果还没有任何数字,就像在 OP 中一样,应该在它们的位置插入一些数字。Renumber 可以处理实际的排序,它只基于第一个数字。

在此示例中,我<C-v>用于在要编号的所有行上插入起始编号。

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

使用两个步骤

:Renumber s2

于 2012-03-28T10:08:06.397 回答