我想合并Vim中的两个行块,即取行k到l并将它们附加到行m到n。如果您喜欢伪代码解释:[line[k+ I] + line[m+ I] for I in range(min(l-k, n-m)+1)]。

例如,

abc
def
...

123
45
...

应该成为

abc123
def45

有没有一种很好的方法来做到这一点,而无需手动逐行复制和粘贴?


当前回答

正如在其他地方提到的,块选择是可行的方法。但是你也可以使用以下的任何变体:

:!5 .尾部-n - 6% |粘贴-d '\0' % - |头部-n

此方法依赖于UNIX命令行。创建粘贴实用程序是为了处理这种行合并。

PASTE(1)                  BSD General Commands Manual                 PASTE(1)

NAME
     paste -- merge corresponding or subsequent lines of files

SYNOPSIS
     paste [-s] [-d list] file ...

DESCRIPTION
     The paste utility concatenates the corresponding lines of the given input files, replacing all but the last file's newline characters with a single tab character,
     and writes the resulting lines to standard output.  If end-of-file is reached on an input file while other input files still contain data, the file is treated as if
     it were an endless source of empty lines.

其他回答

一个优雅而简洁的Ex命令可以通过 组合使用:global、:move和:join命令。假设 第一个行块从缓冲区的第一行开始 光标位于第一行的前一行 行第二块,命令如下。

:1,g/^/''+m.|-j!

有关此技术的详细说明,请参阅我对 一个本质上相同的问题“如何实现“粘贴-d '␣'” 在Vim中的行为?”

我觉得不要弄得太复杂。 我会设置virtualedit (:设置virtualedit =) 选择123块和下面所有的。 把它放在第一列之后:

abc    123
def    45
...    ...

并将其中的多重空格移除为1个空格:

:%s/\s\{2,}/ /g

要连接行块,您必须执行以下步骤:

去第三行,jj 进入可视块模式:CTRL-v 将光标锚定到行尾(对于不同长度的行很重要):$ 进入最后:CTRL-END 切块:x 转到第一行的末尾:kk$ 粘贴到这里:p

这个动作不是最好的(我不是专家),但它像你想要的那样工作。希望会有一个更短的版本。

以下是前提条件,所以这个技巧可以很好地工作:

起始块的所有行(在问题abc和def中的示例中)具有相同的XOR长度 起始块的第一行是最长的,你不关心中间的额外空格)XOR 起始块的第一行并不是最长的,你可以在末尾添加空格。

我将使用复杂重复:)

鉴于这种:

aaa
bbb
ccc

AAA
BBB
CCC

将光标放在第一行,按下以下命令:

qa}jdd''pkJxjq

然后按下@a(随后可以使用@@),需要多少次就按多少次。

你应该得到:

aaaAAA
bbbBBB
cccCCC

(加上换行符。)

解释:

Qa开始记录一个复杂的重复 }跳转到下一个空行 JDD删除下一行 回到上次跳跃前的位置 P将删除的行粘贴到当前行下面 kJ将当前行附加到前一行的末尾 x删除J在合并行之间添加的空格;如果你需要空间,你可以省略这个 看下一行 Q结束复杂的重复记录

在此之后,您可以使用@a运行存储在a中的复杂重复,然后您可以使用@@重新运行上次运行的复杂重复。

样本数据与rampion的相同。

:1,4s/$/\=getline(line('.')+4)/ | 5,8d