Vim:行ごとに貼り付ける


8

私が含んでいるファイルがあるとしましょう:

xxx
yyy
zzz

そして別のファイル:

kkk
qqq
ppp

取得したい:

xxxkkk
yyyqqq
zzzppp

それはいくつかのコマンドでVimで可能ですか?(私はVISUAL BLOCKを使用しようとしましたが、成功しませんでした)。

私の特定のケースでは、貼り付ける行が多い2つの大きなファイルがあるので、答えはいくつかのシェルコマンドになる可能性もありますが、同じファイル内でもそれを行う方法があるかどうか知りたいです。

回答:


12

コマンドラインから、あなたは試すことができます

paste -d '\0' file1 file2 > file3

それはまさにあなたが望んでいることです。

のビジュアルブロックモードvimもこのタスクに最適です。正しく実行しましたか?あなたがすべき

  • ビジュアルブロックモードに移動
  • テキストを選択しy、ヤンクするために押します
  • の左上隅にあるデータを貼り付けるデータ(最後x)に移動し、を押しpます。

Visual Blockに貼り付けていました...それがまさに私がやりたかったことです。ありがとうございました。
Fabio F.

1
少なくともGNU Coreutilsでpaste -d '' ...動作します。興味深いことに、coreutilsのマンページと情報ページには、シングルUnix仕様で指定されているにもかかわらず、「\ 0」が記載されていないようです。
derobert 2014年

5

編集時に直接行うことができますfile1。vimで:切り替えるタイプcommand mode。次に、次のように入力します。

%!paste -d '' - file2

3

これは、Vimだけを使用して同じファイル内で実行する方法です。

これにはいくつかのキーマッピングが含まれます。いくつかのリストを単純なテキストで表のような構造に配置したいと思ったときに、これを思いつきました。

これは、}キー(右中括弧)を使用して段落の境界をスキップします。(中かっこはミラー化されています、ところで:{ファイルの先頭に向かってスキップし、}末尾に向かってスキップします。)

だから...あなたはこのようなデータファイルがあると仮定します(これはline :が:set nuでオンになっていると仮定しています):

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

行#4が空行(空白なし)であることが重要です。その理由については後で説明します。

次のマップコマンドを実行します。
: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"は1回限りのユーティリティマクロに役立つと思います。大文字のQ(マップQなど)やfnctキーなども使用できます。

ここで(ナビゲーションモードで)「q」を押すと、vimは次の一連のキーストロークを実行します。

   mw}jdd'wpkJj

もちろんどちらが意味不明なように見えるので、私はそれをアクションごとに分解して(以下の^^を使用)、何が起こっているのかを簡単に追跡できるようにします。

mw}jdd'wpkJj
^^

MWのマークという名前の場所、ここでの名前は「W」です。私はデフォルトで「w」を使用します(これは私の「w」動作場所と考えます。一貫性がある限り、azからの任意の名前付き場所が機能します。
「w」は、カーソルをこの行に戻したい。

mw}jdd'wpkJj
  ^

ここには、カーソルを次の段落境界にジャンプさせる右巻き}があります。つまり、カーソルが次の空の行(この例ではline#4)に移動します。(これが、行#4が空行でなければならない理由です。空白がないと、}はそれを境界と見なしません。)

mw}jdd'wpkJj
   ^

jは 1本のラインを下ります。これは、昔ながらのvi "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は、それはそれで「KKK」とライン#5で現在の行を削除しますので、「行削除」編集コマンドです。行を削除すると、デフォルトの貼り付けバッファーにも入れられます。これを利用して、「kkk」を「xxx」の隣の行#1の目的の場所に戻します。

mw}jdd'wpkJj
      ^^

「W (シングルクオートw)のシーケンスは、ライン#1の上にカーソルを置く『W』のための私達のブックマークにカーソル背中を、ジャンプします。

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」がどのようにline#2になったかに注意してください。(カーソルがどこにあるのか簡単に説明することはできません...それは実際には行#2の先頭にあるはずです)。
私たちは近くにいますが、まだそこまでは行きません...

mw}jdd'wpkJj
         ^^

小文字のkはカーソルをline#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」ナビゲーションです。これはカーソルをline#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」に下ったら、カーソルを行1にジャンプして戻し(左のカーリー、{、それでうまくいきます)、「mmm」を使い続けます。配置方法が気に入らない場合は、u(元に戻す)を少し押したまま、「境界」の線がどこから始まるかを微調整します。

これは、説明するよりもはるかに簡単に機能するものの1つです。何千もの行を結合するためには使用しないと思いますが、数十、時には数百の行に便利です。

+----------:---------------------------
|   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

「join + x」は、2つの行を結合した直後に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を実行するには、おそらく数十の方法があります。
「フィールド」区切り文字が重要な場合は、通常、グローバル検索と置換を使用して単純な一意のシーケンスをすべての行の最後に配置し、先に進んで列を希望の方法で結合し、すべて置換して特定のセパレータを取得します。

とにかく、これはほんの一例です。面白かったと思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.