Vim:逐行粘贴行


8

假设我有一个包含以下内容的文件:

xxx
yyy
zzz

和另一个文件:

kkk
qqq
ppp

我想获得:

xxxkkk
yyyqqq
zzzppp

在Vim中使用某些命令可以做到吗?(我尝试使用VISUAL BLOCK,但没有成功)。

在我的特定情况下,我有两个要粘贴很多行的大文件,因此答案也可能是一些shell命令,但是我想知道即使在同一文件中也有办法做到这一点。

Answers:


12

从命令行,您可以尝试

paste -d '\0' file1 file2 > file3

那正是您想要的。

可视块模式vim也非常适合此任务。您确定操作正确吗?你应该

  • 进入可视块模式
  • 选择文本,然后按y洋基
  • 转到要粘贴数据(最后一个x)的左上角的另一个文件,然后按p

我正在粘贴Visual Block ...这正是我想要做的。谢谢。
Fabio F.

1
至少与GNU Coreutils一起使用paste -d '' ...也可以。有趣的是,即使在Single Unix Spec中指定了coreutils的联机帮助页和信息页,它们似乎也没有记录'\ 0'。
derobert 2014年

5

您可以在编辑时直接进行操作file1。键入:以切换到command modevim。然后输入:

%!paste -d '' - file2

3

这是仅使用Vim在同一文件中完成此操作的一种方法。

它涉及一些键映射。当我想将多个列表排列成简单文本形式的表状结构时,我想到了这一点。

这取决于}键(右花括号)来跳过段落边界。(括号被镜像,顺便说一句:{跳到文件顶部,}跳到末尾。)

所以...假设您有一个像这样的数据文件(假设使用#:set nu打开了line#):

+---------------  
| 1 xxx    (cursor on line#1)  
| 2 yyy  
| 3 zzz  
| 4   
| 5 kkk  
| 6 qqq  
| 7 ppp  
+---------------  

重要的是第4行是一个空行(没有空格),我稍后将解释原因。

执行以下map命令
::map q mw} jdd'wpkJj

它将“ q”键绑定到一个12个字符的程序,我将在下面详细介绍。

当您点击“ q”时,它将执行该程序;请注意,从第1行开始的光标现在位于下一行,可以再次点击“ q”。您可能已经注意到“ xxx kkk”之间有一个空格字符;如果您不想这样做,请参阅“多余的空格字符是什么?”。下面,接近尾声。

+---------------
| 1 xxx kkk
| 2 yyy   (cursor on line #2)
| 3 zzz
| 4 
| 5 qqq
| 6 qqq
| ~
+---------------

以下是映射的细分:

   :map q mw}jdd'wpkJj
   ^

冒号使您进入命令模式,因此我们可以发出“ map”命令。

   :map q mw}jdd'wpkJj
    ^^^^^

map q将q与以下字符序列绑定。请注意,“ q”只是我通常的“映射到”键;您可以使用其他键。默认情况下,小写的q被映射为开始宏记录;因为我很少(从来没有?)使用过,我发现“ q”对一次性实用程序宏更有帮助。您也可以使用大写Q(例如map Q)或fnct键等。

现在,每当您按“ q”(在导航模式下)时,vim都会执行以下一系列击键:

   mw}jdd'wpkJj

当然,哪一个看起来像是胡言乱语,所以我将其逐个动作分解(下面带有^^),以便更轻松地了解正在发生的事情。

mw}jdd'wpkJj
^^

兆瓦标志着一个指定位置,名称这里是“W”。默认情况下,我使用“ w”(我认为这是我的“ w”工作位置。只要您保持一致,来自z的任何命名位置都可以使用。
当我们执行以下操作时,“ w”将再次显示想要将光标返回到此行。

mw}jdd'wpkJj
  ^

在这里,我们有一个右旋},它将光标向下跳转到下一个段落边界;换句话说,这会将光标移动到下一个空行,在本示例中为第4行。(这就是为什么#4行应为空行;不能有空格,否则}不会将其视为边界。)

mw}jdd'wpkJj
   ^

Ĵ下降一行; 这是老式的“ hjkl”导航。您可能也可以在这里使用向下箭头,我发现“ j”在某种程度上更易于阅读和使用(因为箭头键在各种品牌的笔记本电脑和台式机键盘之间并不总是位于同一位置,但是“ hjkl ”保证始终位于任何QWERTY键盘主行的右侧(这有助于我加快打字速度)。
无论如何,此时光标位于第5行。

+---------------  
| 1 xxx
| 2 yyy  
| 3 zzz  
| 4   
| 5 kkk   (cursor on line#5)
| 6 qqq  
| 7 ppp  
+---------------  

mw}jdd'wpkJj
    ^^

DD是“删除线”编辑命令,所以它删除当前行,这是行#5与在其上的“KKK”。删除该行还将其放入默认的粘贴缓冲区中,我们将利用该缓冲区将“ kkk”带回到第1行中“ xxx”旁边的所需位置。

mw}jdd'wpkJj
      ^^

“W (单引号w)的顺序跳光标回到我们的书签‘W’,这使光标上线#1。

mw}jdd'wpkJj
        ^

小写的“ p”将光标后的当前默认缓冲区(带有“ kkk”,您会记得)。由于缓冲区包含以前的第5行,因此我们的文件现在看起来像这样:

+---------------
| 1 xxx
| 2 kkk    (cursor on line#2, after the freshly restored "kkk")
| 3 yyy
| 4 zzz
| 5 
| 6 qqq
| 7 ppp
+---------------

注意“ kkk”如何成为第2行。(我无法轻易说明光标到那里的位置……它实际上应该在第2行的开头)。
我们已经接近了,但还没到那儿...

mw}jdd'wpkJj
         ^^

小写的k将光标跳到第1行(再次是“ hjkl”导航),大写的J将下一行连接到当前行,使我们的文件看起来像这样(光标仍然位于第1行, x和k):

+---------------
| 1 xxx kkk    (cursor on line #1, between 'xxx' and 'kkk')
| 2 yyy
| 3 zzz
| 4 
| 5 qqq
| 6 ppp
+---------------


mw}jdd'wpkJj
           ^

最后一个j再次是“ hjkl”导航,它将光标向下移动到第2行,这很方便,因为这是我们要应用q的下一行。
无论如何,它将看起来像这样:

+---------------
| 1 xxx kkk
| 2 yyy       (cursor on #2)
| 3 zzz
| 4 
| 5 qqq
| 6 ppp
+---------------

如果再次点击“ q”,它将看起来像这样(注意光标位于第3行)。

+---------------
| 1 xxx kkk
| 2 yyy qqq
| 3 zzz        (cursor on #3)
| 4 
| 5 ppp
+---------------

冲洗并根据需要重复。对于较长的列表,我觉得这很方便,因为它使我(相当)轻松地建立了列。

这是一个更长的例子。在第7行添加空白行会导致“ ggg”首先堆叠在下一列中。下降到“ lll”后,将光标跳回第一行(向左卷曲,{,效果很好),并继续使用“ mmm”。如果您确定自己不太喜欢它的排列方式,请按住u(撤消)并微调“边界”行的位置,然后重新开始。

这是比解释工作容易得多的事情之一。虽然我认为我不会将其用于连接成千上万的行,但我发现它适用于数十个行,有时甚至数百个行。

+----------:---------------------------
|   before : after
+----------:---------------------------
|  1 aaa   :  1 aaa ggg mmm sss yyy
|  2 bbb   :  2 bbb hhh nnn ttt zzz
|  3 ccc   :  3 ccc iii ooo uuu
|  4 ddd   :  4 ddd jjj ppp vvv
|  5 eee   :  5 eee kkk qqq www
|  6 fff   :  6 fff lll rrr xxx
|  7       :-------------------------
|  8 ggg 
|  9 hhh 
| 10 iii 
| 11 jjj 
| 12 kkk 
| 13 lll 
| 14 mmm 
| 15 nnn 
| 16 ooo 
| 17 ppp 
| 18 qqq 
| 19 rrr 
| 20 sss 
| 21 ttt 
| 22 uuu 
| 23 vvv 
| 24 www 
| 25 xxx 
| 26 yyy 
| 27 zzz
+----------

那多余的空间字符呢?
Join命令的部分行为是,它在连接的行之间放置了一个空格。
如果您不希望在“ xxx kkk”之间留空格,则可以
在字符串中添加删除命令(x):

simple join (space char):  :map q mw}jdd'wpkJj
join + x (kills space):    :map q mw}jdd'wpkJxj
join w/comma:              :map q mw}jdd'wpkJR,^[j

“加入+ X”通过杀死空间X权后,我们两线连接在一起。 在导航模式下,x会删除光标恰巧位于其上的任何字符,在这种情况下,这是有问题的空格字符。

“用逗号连接”用逗号替换空格。几乎是相同的,但我们将逐步介绍最后一部分,与上一个示例稍有不同。

:map q mw}jdd'wpkJR,^[j
                  ^

[R将让我们进入编辑模式(特别是替换模式,这将覆盖任何字符,我们类型)。

 :map q mw}jdd'wpkJR,^[j
                    ^

从字面上类型逗号,其是覆盖在该点有问题的空间。

 :map q mw}jdd'wpkJR,^[j
                     ^^

然后^ [表示转义字符,它退出编辑模式并使我们回到导航模式。
现在,我们准备好最后的j将我们带到下一行。

要映射转义字符,您需要按^ Q(windows)或^ V(linux&unix),然后按Esc键(如果不这样,则Esc字符将中止命令,您的左手想知道为什么可能使用复杂的地图定义消失了)。在Windows上将其输入Vim时,必须输入以下顺序:

:map q mw}jdd'wpkJR,<Ctr-Q><Esc>j

所以。Vim可能有数十种方法来执行这种操作。
当“字段”定界符很重要时,我通常在每行的末尾放置一个简单的唯一序列,进行全局搜索和替换,继续按照我想要的方式加入各列,然后全部替换以获得我想要的特定分隔符。

无论如何,这只是一个例子。希望您觉得有趣。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.