我想把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有没有一个很好的方法来做到这一点,而不复制和粘贴手动逐行?
发布于 2012-05-25 19:44:06
您当然可以使用单个复制/粘贴(使用块模式选择)来完成所有这些操作,但我猜这不是您想要的。
如果你只想用Ex命令来做这件事
:5,8del | let l=split(@") | 1,4s/$/\=remove(l,0)/将转变
work it
make it
do it
makes us
harder
better
faster
stronger
~转到
work it harder
make it better
do it faster
makes us stronger
~更新:--这么多人投票的答案--值得更彻底的解释。
在Vim中,您可以使用管道字符(|)来链接多个Ex命令,因此上面的内容相当于
:5,8del
:let l=split(@")
:1,4s/$/\=remove(l,0)/许多Ex命令接受一系列行作为前缀参数--在上述情况下,5,8在del之前,1,4在s///之前指定命令在哪些行上操作。
del删除给定的行。它可以使用一个寄存器参数,但是当没有给出一个参数时,它会将行转储到未命名的寄存器@"中,就像正常模式下的删除一样。然后,let l=split(@")使用默认分隔符:空格将已删除的行拆分为列表。若要正确处理已删除行中有空格的输入,请执行以下操作:
more than
hour
our
never
ever
after
work is
over
~我们需要指定一个不同的分隔符,以防止将"work is“拆分为两个list元素:let l=split(@","\n")。
最后,在替换s/$/\=remove(l,0)/中,我们将每行的末尾($)替换为表达式remove(l,0)的值。remove(l,0)修改列表l,删除并返回其第一个元素。这样我们就可以按照读取的顺序替换已删除的行。相反,我们可以使用remove(l,-1)以相反的顺序替换已删除的行。
发布于 2012-05-26 07:09:30
通过组合:global、:move和:join命令,可以获得一个优雅而简洁的Ex命令来解决这个问题。假设第一个行块从缓冲区的第一行开始,并且光标位于紧接第二块第一行的行上,则命令如下所示。
:1,g/^/''+m.|-j!有关此技术的详细说明,请参见my answer中本质上相同的问题“How to achieve the “paste -d '␣'” behavior out of the box in Vim?”。
发布于 2012-05-25 19:41:02
要连接行块,必须执行以下步骤:
转到第三行:jj
CTRL-v
$
CTRL-END
x
kk$
p这个运动并不是最好的运动(我不是专家),但它的工作方式是你想要的。希望会有一个较短的版本。
这里有一些前提条件,所以这种技术很好地工作:
起始块的所有行(在问题XOR
def中的示例中)都具有相同的长度,起始块的第一行是最长的,并且您不关心中间的附加空格),XOR
https://stackoverflow.com/questions/10760326
复制相似问题