如何复制每行11次,将每行的最后一个“ 1”从2-12递增


9

我在文件中有很多行,我想将每行复制11次(将每行变成12行),并增加每行的最后一个“ 1”,以使12行从“ 1”到“ 12”,最初是“ 1”。每行中可能还会有其他出现的“ 1”,但是我要增加的“ 1”将始终是每行中的最后一个出现。另一种看待它的方法是最后一个“ 1”总是在“ / nt /”之后-像在“ / nt / 1”中一样(并且它始终是每行中唯一出现的“ / nt / 1”) 。

因此,例如,如果我有:

1stlineblahblahblah/nt/1blah
2ndlineblahblahblah/nt/1blah
3rdlineblahblahblah/nt/1blah

我想把它变成:

1stlineblahblahblah/nt/1blah
1stlineblahblahblah/nt/2blah
1stlineblahblahblah/nt/3blah
1stlineblahblahblah/nt/4blah
1stlineblahblahblah/nt/5blah
1stlineblahblahblah/nt/6blah
1stlineblahblahblah/nt/7blah
1stlineblahblahblah/nt/8blah
1stlineblahblahblah/nt/9blah
1stlineblahblahblah/nt/10blah
1stlineblahblahblah/nt/11blah
1stlineblahblahblah/nt/12blah
2ndlineblahblahblah/nt/1blah
2ndlineblahblahblah/nt/2blah
2ndlineblahblahblah/nt/3blah
...

我以前找到了命令:

:for i in range(0,12) | put ='1stlineblahblahblah/nt/'.i.'blah' | endfor

可以达到这个目的,但是我必须为每行手动运行此命令,然后自己输入(或复制并粘贴)每一行。有没有一种方法可以处理文件中已经存在的行,并仅运行一个命令就可以按照我描述的方式将每一行变成十二行?

在此先感谢任何可以帮助我的人。我也只想指出,这是我的第二个问题,我很高兴为第一个问题获得了几种快速有效的解决方案,对此我深表感谢。

Answers:


8

这是解决问题的替代方法:

:%s/\(.*\)1\(.*\)/\=join(map(range(1, 12), 'submatch(1) . v:val . submatch(2)'), "\n")

替换匹配包含“ 1”的每一行,并捕获最后一个“ 1” 之前{c1}和之后{c2}的文本。对于每一个匹配线,从一到十二编号的范围{n}映射到创建12线的形式的{c1}{n}{c2}。每组十二行替换其关联的,最初匹配的行。

请参阅:h sub-replace-expression


2
哇,很棒的一线命令。我记得您对几周前我问的第一个问题也找到了一种简洁的单线解决方案。非常好 非常感谢你。另外,我猜想有一种方法可以将它放在_vimrc文件中,这样我就可以执行一个易于记忆的命令或函数,而无需在上面输入整行(或滚动浏览以前的命令列表),但是我对_vimrc语法还不熟悉,不知道该怎么做。
ablewasiereisawelba

10

你可以这样做

  1. 录制一个宏,然后
  2. 使用globalex命令对文件中的每一行执行n次宏。

录制宏后,请撤消录制时所做的更改,否则第一行将有n + 1条额外的行,而连续行将有n条。

将宏记录到a寄存器中

qayyp$?\d<CR><C-A>q

这会将以下命令记录到寄存器aqa...q)中:

  • yyp:复制当前行
  • $:移至行尾
  • ?\d<CR>:向后搜索一位数字
  • <C-A>:将光标下方的数字加一

录制宏后,请撤消(uu)或删除当前行(dd),以删除在录制宏时所做的更改。然后11使用全局命令为文件中的每一行重复宏(或任意多次):

:g//normal 11@a

2
有效!很好谢谢。我最初有一个问题,是Ctrl-一个突出的一切,而不是加入,因为我在Windows中使用gVim的......但我做了快速搜索,发现这个线程- stackoverflow.com/questions/289681/... -在哪里使用了将nnoremap <kPlus> <Ca> nnoremap <kMinus> <Cx>放在_vimrc中的建议,这样我就可以使用“ +”和“-”键进行加法和减法。另外,对于我来说,全局命令必须为:g // normal 11 @ a,但这很容易理解。谢谢!
ablewasiereisawelba

6

两种方式:

使用宏!

从...开始

1stlineblahblahblah/nt/1blah
2ndlineblahblahblah/nt/1blah
3rdlineblahblahblah/nt/1blah

将光标放在第一行

qqyyp$?\d<CR><Ctrl-a>q
10@q

哪个:

qq 开始将宏记录到q寄存器中

yyp 抽出当前行,并将其粘贴到下面

$?\d<CR> 转到该行的末尾,找到向后看的第一个数字

<Ctrl-a> 递增数量

q 停止录制宏。

这使您拥有:

1stlineblahblahblah/nt/1blah
1stlineblahblahblah/nt/2blah
2ndlineblahblahblah/nt/2blah
2ndlineblahblahblah/nt/3blah

将光标放在第二行。只需根据需要多次重复此宏(例如,使用10 @ q重复十次)。如果要为每行自动执行此过程,请在每行中全局执行该过程:

:g//normal 11@q

或者,使用较新版本的vim:多次粘贴所需的行,可视块选择要增加的数字,然后按g <Ctrl-a>。这将根据需要增加可视块中的所有数字。但是,这是一个更手动的过程。


1
太棒了,我不知道这种g <c-a>方式。感谢分享。
kba与莫妮卡一起站在

1
@fruglemonkey您的答案的第一部分与上述内容相同,但是仍然感谢您。第二部分,我认为不适合我(除非我做错了事),因此我一定不能使用正确的版本。
ablewasiereisawelba

5

我发现将宏用于此类一键式任务最简单。只需开始记录带有q+名称的宏,然后执行一次任务。我在这里看到一项可重复的任务:

  • 选择线
  • yan
  • 粘贴(将使您进入下一行)
  • 转到行尾
  • 回一个字
  • 加一

现在a在正常模式下记录所需的击键来注册:

qayyp$b<c-a>.

再次删除该行以测试执行11次宏是否对一行产生正确的结果:

11@a

是的!因此,让我们再次撤消并在第二个宏中自动化整个过程b

qb11@aj

现在,您可以执行@b到文件末尾,它应该会产生所需的输出。这听起来很复杂,但是一旦您习惯了典型的编辑模式,它实际上就不是真正的了。


我不确定自己做错了什么,但是似乎没有用。我遵循了您所写的内容,但也许我误解了某些内容或未正确执行某些内容。(我得到的是行的第一个数字,而不是行的最后一个数字。)谢谢您的答复。
ablewasiereisawelba

3
我认为第一个宏应该是qaVyp$b<c-a>。或者更好,只是qayyp$b<c-a>
Karl YngveLervåg16年

1
谢谢@KarlYngveLervåg,您是对的,我已修复了宏。
kba与莫妮卡站在一起

2
。哎呀:(感谢能彻底@ablewasiereisawelba我猜宏qqyyp$?\d<CR><Ctrl-a>q通过@fruglemonkey和@jjaderberg是更好,因为它搜索的最后一个数字,我会改变它的完整性。
高宝代表与莫尼卡

2
@kba我只是认为,如果有人花时间和精力来回答我的问题,我至少可以尝试他的解决方案-即使我已经从其他人那里找到了可行的解决方案。我很感谢您的努力-如果能让您感觉更好,您仍然领先于我。:)
ablewasiereisawelba

2

保存以下宏,并将其用于每一行:

qqyy11p/\/\zs1<CR><C-v>10jg<C-a>q

与其他答案的主要区别在于,这利用了g<C-a>对列的选择,该选择以不同的数字递增每行。检查:help v_g_CTRL-A更多信息。我还习惯于\zs选择图案的开始位置,以便光标停在搜索后的数字处。

请注意,您需要使用Vim的最新版本才能正常工作。


1
@fruglemonkey也建议这样做。这是一个很酷的功能,尽管它是相当新的(按vim标准),因为7.4.754尚未发布到所有发行版中。
kba与莫妮卡站在一起

错过了对不起
Vitor

1
@Vitor我只有gVim 7.4,所以我认为我无法做到g<C-a>您所提到的@fruglemonkey,但是感谢您的回复。我应该注意,在尝试宏时-在我进入该g<C-a>部分之前,不是我要增加的最后一个“ 1”字符被突出显示,而是在第一个“ 1”之前的字符”,该字符会被突出显示。(此外,我想应该是yy11p并且10j在宏中,因为我希望添加 11行-总共12行。)
ablewasiereisawelba

1
感谢您的反馈意见。我已经相应地更新了答案。决定使用\zs,但我也可以添加一个lafter <CR>
Vitor

1
您可能在vimrc中具有一些会影响正则表达式搜索的设置。重新尝试从Vim开始vim -u NONE。我已经做到了,而且效果很好!实际上,搜索不可能与第一个匹配,因为它需要前面的斜杠。
Vitor
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.