【问题标题】:How to generate a number sequence in file using vi or Vim?如何使用 vi 或 Vim 在文件中生成数字序列?
【发布时间】:2012-04-11 19:37:54
【问题描述】:

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

例如,对于任意范围的行 ij(其中 i j)在一个在 Vim 中打开的文件,有没有办法从 i 行的第 1 行到第 1 行生成一个数字序列(j - 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 等?

注意:问题“How to add line numbers to range of lines in Vim?”提出了类似的问题,但不一样。

【问题讨论】:

  • 这个插件不能完全解决您的问题,但它对于添加数字列非常有用:VisIncr。文档here。 FWIW。

标签: vim pattern-matching vi sequential


【解决方案1】:

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 重新选择。如果以1开头,则需要手动重新选择,同时省略第一个1

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


【讨论】:

  • 太棒了。使用 Vim 20 年后,我仍然对它的功能感到惊讶。
  • 您制作动画 gif 时是否使用了插件或一些技巧来显示每个按键的文本?
  • 工具名为screenkey,可以在gitlab上找到。
  • 它在 gvim 或 vim 上都对我不起作用。这是一个对我有用的解决方案vim.fandom.com/wiki/Increasing_or_decreasing_numbers。例如。 qa Y p Ctrl-A q 5@a
  • @syam 有意思,能分享一下vim --version的输出吗?
【解决方案2】:

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

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

Nexus 还附带一个 s0 系列对象,它产生 0 作为其第一个 .next() 结果。 s0s1 都使用 1 步增量。所有 Series 对象都有一个 .reset() 方法,该方法将它们设置回它们的初始值。可以像以下调用一样创建新的 Series 对象:

let s2 = Series(0, 2)

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

【讨论】:

    【解决方案3】:

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

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

    :4,8 perldo s/^/++$z . " "/e
    

    【讨论】:

      【解决方案4】:

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

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

      输入:help sub-replace-expression阅读更多内容。

      【讨论】:

      • 谢谢! vim好强大!!试试这个::let i=1 | let j=1 | '&lt;,'&gt;g/^/ s//\=i/ | let c=i+j | let j=i | let i=c
      • 谁能解释一下?
      • 如果我希望前缀数字被零填充怎么办?
      • 当我在 Windows 7 上的 Vim 7.4 上尝试这个时,我得到 E481: No range allowed
      【解决方案5】:

      我认为所有建议的解决方案都很难记住,你可以使用一次,但每次使用时都需要详细了解所有细节(如果你每天使用它少于一次左右)。

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

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

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

      插件的vimball为herehere

      【讨论】:

        【解决方案6】:

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

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

        在本例中,我使用&lt;C-v&gt; 在您要编号的所有行上插入起始编号。

        4G&lt;C-v&gt;4jGI1 &lt;Esc&gt;gv:Renumber

        使用两个步骤

        :Renumber s2

        【讨论】:

          【解决方案7】:

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

          aaa
          bbb
          ccc
          

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

          1 aaa
          bbb
          ccc
          

          然后在第 1 行记录这个宏(&lt;C-a&gt; 表示 CTRL-a):

          qq0yf 0j0P0<C-a>q
          

          解释:

          1. qq:将宏记录到寄存器q
          2. 0:转到第一列。
          3. yf:将所有内容拉到并包括第一个空格(请记住,您的第一行有 1 和一个空格)。
          4. 0jP: 下去把图案粘贴到行首。
          5. 0&lt;C-a&gt;:转到第一列并将数字加一。
          6. q:结束宏录制。

          这给出了:

          1 aaa
          2 bbb
          ccc
          

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

          :.,$norm @q
          

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

          【讨论】:

          • 如果我理解正确,您是在复制以前的数字并增加它。如果数字有更多位数,它会起作用吗? f0 之间的空格是否有原因?
          • 是的,您理解正确。空格很重要,因为您复制了任何内容,包括带有f 的空格,因此您复制了更多数字。所以是的,它适用于多于一位的数字,只是尝试到文件中的第 1449 行:) 当然你可以使用任何其他分隔字符,tab 浮现在脑海中。
          • 哦,单行也不错,但考虑这些通常比只录制宏更乏味。我喜欢宏的易用性和灵活性。
          • @hochl: 考虑 Ex 命令并不比普通模式命令更乏味​​。如果其中一种命令让您使用起来很乏味,则意味着您的 Vim 体验在这些命令之间没有得到很好的平衡。
          • 我经常在我的宏中添加zz 来看看接下来会发生什么。当光标在屏幕底部时很难。
          【解决方案8】:
          :4,8s/^/\=line(".")-3." "    
          

          会做你想做的事

          如果你需要 count=2:

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

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

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

          【讨论】:

          • 这种方法简单、通用且一目了然。
          【解决方案9】:

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

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

          不跨平台。

          【讨论】:

            【解决方案10】:

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

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

            【讨论】:

              猜你喜欢
              • 2018-11-24
              • 2012-11-23
              • 2010-09-09
              • 1970-01-01
              • 2010-12-31
              • 2019-10-23
              • 2016-11-21
              • 2017-02-13
              • 2011-04-14
              相关资源
              最近更新 更多