Merge multiple lines (two blocks) in Vim
我想在Vim中合并两个行块,即取行
例:
1 2 3 4 5 6 7 | abc def ... 123 45 ... |
应该成为
1 2 | abc123 def45 |
没有手动复制和粘贴,有没有一种很好的方法可以做到这一点?
你当然可以通过一次复制/粘贴(使用块模式选择)完成所有这些,但我猜这不是你想要的。
如果您只想使用Ex命令执行此操作
1 | :5,8del | let l=split(@") | 1,4s/$/\=remove(l,0)/ |
会改变
1 2 3 4 5 6 7 8 9 | work it make it do it makes us harder better faster stronger ~ |
成
1 2 3 4 5 | work it harder make it better do it faster makes us stronger ~ |
更新:这个许多赞成票的答案值得更彻底的解释。
在Vim中,您可以使用管道符(
1 2 3 | :5,8del :let l=split(@") :1,4s/$/\=remove(l,0)/ |
许多Ex命令接受一系列行作为前缀参数 - 在上面的例子中,
1 2 3 4 5 6 7 8 9 | more than hour our never ever after work is over ~ |
我们需要指定一个不同的分隔符,以防止"work is"被分成两个列表元素:
")
最后,在替换
可以通过以下方式获得解决问题的优雅简洁的Ex命令
结合
第一个行块在缓冲区的第一行开始,而那个
光标位于紧靠第一行之前的行上
第二个块,命令如下。
1 | :1,g/^/''+m.|-j! |
有关所用技术的详细说明,请参阅我给出的答案
问题"Vim paste -d''开箱即用的行为?"。
要加入行块,您必须执行以下步骤:
运动不是最好的(我不是专家),但它的工作方式与你想要的一样。希望会有更短的版本。
以下是先决条件,因此这项技术运作良好:
-
起始块的所有行(在问题
abc 和def 中的示例中)具有相同的长度XOR - 起始块的第一行是最长的,你不关心其中的额外空格)XOR
- 起始块的第一行不是最长的,你可以在末尾添加额外的空格。
这是我怎么做的(光标在第一行):
1 | qama:5<CR>y$'a$p:5<CR>dd'ajq3@a |
你需要知道两件事:
- 第二组第一行开始的行号(在我的情况下为5),和
- 每组中的行数(在我的示例中为3)。
这是发生了什么:
-
qa 将下一个q 的所有内容记录到a 中的"缓冲区"中。 -
ma 在当前行上创建标记。 -
:5 进入下一组。 -
y$ 猛拉其余部分。 -
'a 返回前面设置的标记。 -
$p 贴在行尾。 -
:5 返回第二组的第一行。 -
dd 删除它。 -
'a 返回标记。 -
jq 向下移动一行,并停止录制。 -
3@a 重复每一行的动作(在我的情况下为3)
如其他地方所述,块选择是要走的路。但您也可以使用以下任何变体:
此方法依赖于UNIX命令行。创建
1 2 3 4 5 6 7 8 9 10 11 12 | 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. |
我不认为这太复杂了。
我只想设置virtualedit
(
选择块123以及下面的全部。
把它放在第一列之后:
1 2 3 | abc 123 def 45 ... ... |
并删除1个空格之间的多个空格:
1 | :%s/\s\{2,}/ /g |
样本数据与rampion相同。
1 | :1,4s/$/\=getline(line('.')+4)/ | 5,8d |
我会使用复杂的重复:)
鉴于这种:
1 2 3 4 5 6 7 | aaa bbb ccc AAA BBB CCC |
将光标放在第一行的第一个"a"处,按以下键:
1 | qq}jdd''$pkJj0q |
然后根据需要多次按
你最终应该:
1 2 3 | aaaAAA bbbBBB cccCCC |
(加上换行符。)
可以有很多方法来实现这一目标。我将使用以下两种方法中的任何一种合并两个文本块。
假设第一个块在第1行,第二个块从第10行开始,光标的初始位置在第1行。
( n表示按回车键。)
1 2 3 4 5 6 7 | 1. abc def ghi 10. 123 456 789 |
使用命令宏:复制,粘贴和连接。
qaqqa:+9y
pkJjq2@a10G3dd
使用命令宏在第n行号移动一行并加入。
qcqqc:10m .
kJjq2@c