连接每 3 行以制表符分隔 (vim)
Join every 3 lines spearated with tab (vim)
我想用制表符作为分隔符连接文件的每 3 行。如何使用 Vim 完成此操作?
我知道宏机制,但我正在寻找更优雅的东西。
我建议使用宏,手动执行一次并将其绑定到一个键中,但如果您想经常使用它,我建议您在 .vimrc
[=11 中添加一个映射命令=]
我会使用两个 :help :normal
命令……
在每一行添加一个制表符:
:%normal A^i
用 <C-v><Tab>
获得文字 ^i
。
加入每组三行:
:%normal 3J
事实证明这行得通:
:g/\n/,+1s//\t
:global
将匹配缓冲区中的每一行(或者在范围内,如果你传递一个范围。)
/\n/
被用作将匹配每一行的正则表达式,在本例中,是在换行符本身上。我们可以使用 /^/
之类的东西(或者 /./
或 /\S/
来匹配非空行或非空行),这里我们使用 /\n/
因为我们想要在以下 :s
中使用该模式,因此我们可以在此处省略它以使用相同的模式。
然后,对于 :g
处理的每一行,我们使用该行的范围直到第 +1
行。这意味着两行,在这种情况下,当前行和下一行。由于我们要连接三行,我们要替换两行的换行符,所以从当前行到第 +1
行。 (您可以将其概括为使用 +
您要加入的块中的行数减去二。)
最后,我们执行替换 s//\t
,相当于 s/\n/\t/
(使用空模式将匹配之前使用的 on,在本例中传递给 :g
.) 此 :substitute
将用制表符替换匹配的换行符,有效地连接匹配的行。由于我们使用两行的范围,它一次只会执行两行,有效地替换两个换行符,这将连接三行。
这是有效的,因为当对受影响的行进行编辑时,:global
的方式有效。它首先“标记”应该执行的行,但是如果该行不再存在,它将跳过它。因此,虽然它会首先标记每一行,但当 :s
将每第二行和第三行连接到块中的第一行时,它们上的标记将不再存在,因此最终结果是 :g
不会再次尝试处理这一行,而是会继续到下一个“标记”行,然后它将成为下一个块的开始。
我想用制表符作为分隔符连接文件的每 3 行。如何使用 Vim 完成此操作?
我知道宏机制,但我正在寻找更优雅的东西。
我建议使用宏,手动执行一次并将其绑定到一个键中,但如果您想经常使用它,我建议您在 .vimrc
[=11 中添加一个映射命令=]
我会使用两个 :help :normal
命令……
在每一行添加一个制表符:
:%normal A^i
用
<C-v><Tab>
获得文字^i
。加入每组三行:
:%normal 3J
事实证明这行得通:
:g/\n/,+1s//\t
:global
将匹配缓冲区中的每一行(或者在范围内,如果你传递一个范围。)
/\n/
被用作将匹配每一行的正则表达式,在本例中,是在换行符本身上。我们可以使用 /^/
之类的东西(或者 /./
或 /\S/
来匹配非空行或非空行),这里我们使用 /\n/
因为我们想要在以下 :s
中使用该模式,因此我们可以在此处省略它以使用相同的模式。
然后,对于 :g
处理的每一行,我们使用该行的范围直到第 +1
行。这意味着两行,在这种情况下,当前行和下一行。由于我们要连接三行,我们要替换两行的换行符,所以从当前行到第 +1
行。 (您可以将其概括为使用 +
您要加入的块中的行数减去二。)
最后,我们执行替换 s//\t
,相当于 s/\n/\t/
(使用空模式将匹配之前使用的 on,在本例中传递给 :g
.) 此 :substitute
将用制表符替换匹配的换行符,有效地连接匹配的行。由于我们使用两行的范围,它一次只会执行两行,有效地替换两个换行符,这将连接三行。
这是有效的,因为当对受影响的行进行编辑时,:global
的方式有效。它首先“标记”应该执行的行,但是如果该行不再存在,它将跳过它。因此,虽然它会首先标记每一行,但当 :s
将每第二行和第三行连接到块中的第一行时,它们上的标记将不再存在,因此最终结果是 :g
不会再次尝试处理这一行,而是会继续到下一个“标记”行,然后它将成为下一个块的开始。