繁体   English   中英

Vim:将选择的每一行的第一个单词替换为列表中的数字

[英]Vim: Replace first word on each line of selection with number in list

我有一个很大的文件,其中包含一个带有混杂数字的选择。 它应该是1、2、3,...的序列,但有几行搞砸了。 我想改变像

酒吧

1个foobar

12345 foobar

6546458 foobar

4个foobar

酒吧

1个foobar

2 foobar

3 foobar

4个foobar

我知道我可以使用3,$类的东西来选择我关心的行,并put = range(1,1000)来创建以所需数字​​开头的新行,但是我想将这些数字放在当前有数据的行上,而不是新行。 混杂的数字长几个字符,但总是一个字。 谢谢。

请执行下列操作:

:let i=1
:g/^\d\+/s//\=i/|let i=i+1

总览

设置一些变量( let i=1 )用作我们的计数器。 在以数字( :g/^\\d\\+/ )开头的每一行中,我们执行替换( :s//\\=i/ ),以用我们的计数器( \\=i )替换模式,然后增加我们的计数器( let i=i+1 )。

为什么要使用:g呢? 为什么不只是:s

您可以使用替换命令来完成此操作,但是sub-replace-expression \\=需要一个表达式来求值(请参见:h sub-replace-expression )。 因为let i = i + 1是一条语句,所以它将无用。

有几种方法可以解决此问题:

  • 创建一个使变量递增然后返回的函数
  • 请改用数组,然后(原位)更改内部数字,然后将值返回数组之外。 例如map(arr, 'v:val+1')[0]
  • 如果每行只有1个替换,则从上面执行:g技巧

使用就地数组修改的完整示例:

:let i=[1]
:%s/^\d\+/\=map(i,'v:val+1')[0]

就个人而言,我将使用您能记住的任何方法。

更多帮助

:h :s
:h sub-replace-expression
:h :g
:h :let
:h expr
:h map(
:h v:val
/^\d\+\s  -- Searches for the first occurrence
ciw0<Esc> -- Replaces the word under cursor with "0"
yiw       -- Copies it
:g//norm viwp^Ayiw
          -- For each line that matches the last search pattern,
          --   Replace the current word with copied text,
          --   Increment it,
          --   Copy the new value.

<Esc>只是Esc^A输入为Ctrl + VCtrl + A

您可以使用以下功能:

function Replace()
    let n = 1 
    for i in range(0, line('$'))
        if match(getline(i), '\v^\d+\s') > -1
            execute i . 's/\v^\d+/\=n/'
            let n = n + 1 
        endif
    endfor
endfunction

它遍历整个文件,检查每行是否以数字开头,后跟空格字符,并用随每次更改而增加的计数器进行替换。

像这样称呼它:

:call Replace()

在您的示例中得出:

foo
bar
1 foobar
2 foobar
3 foobar
4 foobar

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM