4

我有一个文件,我想做以下事情。

- copy every n lines starting from m (m,m+n,m+2n, ...)
- copy line number 2, 5, 27, ... by specifying line numbers.

谢谢

4

2 回答 2

7

要复制每 N 行,您可以使用:global选择行的表达式:

:let @a = ''
:g/^/if line('.') % 3 == 0 | yank A | endif

对于显式行,我会依次调用:yank命令:

2yank a | 5yank A | 27yank A

这使用拉入大写寄存器来附加到它。

于 2013-07-08T10:24:11.263 回答
1

除了:gIngo 发布的解决方案,您还可以使用:s命令。

首先,您需要准备图案。例如,要显式匹配每三行,您可以使用 pattern\%3l\|\%6l\|\%9l等。

所以首先让我们将生成的模式保存在一个变量中(为了简化一点,我们只考虑前 100 行):

:let lines=range(3,100,3)

这将创建一个所有行号的列表,从 3 开始并以 3 递增,注意,如果您需要一些不遵循任何算术规则的特殊行号,只需将列表定义为:

:let lines=[2,5,26,57,99]

然后我们需要从中生成一个模式,我们可以在:s命令中使用它:

:call map(lines, '''\%''.v:val.''l''')

这会将行号转换为表单\%编号l的模式。所以我们有一个匹配每个所需行的模式,但首先我们需要初始化一个结果列表变量:

:let result = []

我们现在可以将其提供给:s命令:

:exe ":%s/". join(lines, '.*\|'). '/\=add(result, submatch(0))/n'

所有匹配的行现在都包含在列表中result,例如可以使用以下命令复制到剪贴板:

:let @+=join(result, "\n")

或者您可以将其粘贴到暂存缓冲区中:

:new +exe\ append(0,result)

(注意,exe 和 append 调用之间的空格需要转义)。

另请注意,此解决方案至少需要Vim Patch 7.3.627

根据情况,我会使用这种方法或 Ingo 指出的方法。

于 2013-07-08T18:49:03.910 回答