Vim: menempelkan baris demi baris


8

Misalkan saya memiliki file yang berisi:

xxx
yyy
zzz

dan file lain:

kkk
qqq
ppp

Saya ingin mendapatkan:

xxxkkk
yyyqqq
zzzppp

Apakah itu mungkin di Vim dengan beberapa perintah? (Saya sudah mencoba menggunakan VISUAL BLOCK tetapi tidak berhasil).

Dalam kasus khusus saya, saya memiliki dua file besar dengan banyak baris untuk ditempel sehingga jawabannya juga bisa menjadi beberapa perintah shell tetapi saya ingin tahu apakah ada cara untuk melakukannya bahkan di dalam file yang sama.

Jawaban:


12

Dari baris perintah, Anda bisa mencoba

paste -d '\0' file1 file2 > file3

Itu tepat seperti yang Anda inginkan.

Mode Blok Visual dalam vimjuga sangat cocok untuk tugas ini. Apakah Anda yakin melakukannya dengan benar? Kamu harus

  • Masuk ke mode blok visual
  • Pilih teks dan tekan yuntuk menarik
  • Pergi ke file lain, di sudut kiri atas untuk menempelkan data (terakhir x) dan tekan p.

Saya menempel di Blok Visual ... itulah yang ingin saya lakukan. Terima kasih.
Fabio F.

1
Setidaknya dengan GNU Coreutils, paste -d '' ...juga berfungsi. Menariknya, halaman manutage dan info coreutils tampaknya tidak mendokumentasikan '\ 0', meskipun itu ditentukan dalam Single Unix Spec.
derobert

5

Anda bisa melakukannya langsung saat mengedit file1. Ketik :untuk beralih ke command modevim. Kemudian ketik:

%!paste -d '' - file2

3

Berikut cara untuk melakukannya dalam file yang sama hanya menggunakan Vim.

Ini melibatkan beberapa pemetaan kunci. Saya datang dengan ini sekali ketika saya ingin mengatur beberapa daftar ke dalam struktur seperti tabel dalam teks sederhana.

Ini bergantung pada tombol } (kurung kurawal kanan) untuk melewati batas paragraf. (Kurung dipantulkan, btw: { melompati bagian atas file dan } di akhir.)

Jadi ... misalkan Anda memiliki file data seperti ini (ini mengandaikan bahwa baris # diaktifkan dengan : set nu ):

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

Penting bahwa baris # 4 adalah baris kosong (tidak ada spasi), saya akan menjelaskan mengapa sebentar lagi.

Jalankan perintah peta berikut
:: map q mw} jdd'wpkJj

Ini mengikat kunci "q" ke program 12 karakter, yang akan saya uraikan secara terperinci di bawah ini.

Ketika Anda menekan "q" itu akan menjalankan program itu; perhatikan bahwa kursor Anda, yang dimulai pada baris # 1 sekarang pada baris berikutnya, siap untuk menekan "q" lagi. Anda mungkin telah memperhatikan ada karakter spasi antara "xxx kkk"; jika Anda tidak menginginkannya, lihat "Bagaimana Dengan Karakter Luar Angkasa?" di bawah, mendekati akhir.

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

Berikut ini rincian pemetaan:

   :map q mw}jdd'wpkJj
   ^

Tanda titik dua membawa Anda ke mode perintah sehingga kami dapat mengeluarkan perintah "peta".

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

map q mengikat q dengan urutan karakter berikut. Perhatikan bahwa "q" hanya kunci "map to" saya yang biasa; Anda dapat menggunakan tombol lain. Secara huruf kecil default q dipetakan untuk memulai perekaman makro; karena saya jarang (tidak pernah?) menggunakan yang saya temukan "q" lebih bermanfaat untuk makro utilitas satu kali. Anda juga dapat menggunakan Q huruf besar (misalnya peta Q) atau kunci fnct atau sebagainya.

Sekarang setiap kali Anda menekan "q" (dalam mode navigasi), vim akan menjalankan serangkaian penekanan tombol ini:

   mw}jdd'wpkJj

Yang tentu saja terlihat seperti omong kosong total, jadi saya akan memecahnya tindakan-demi-tindakan (dengan ^^ di bawah) untuk membuatnya lebih mudah untuk mengikuti apa yang terjadi.

mw}jdd'wpkJj
^^

The mw menandai lokasi yang bernama, nama di sini adalah 'w'. Saya menggunakan 'w' secara default (saya menganggap itu sebagai 'lokasi w'orking saya. Setiap lokasi bernama, dari az akan bekerja, selama Anda konsisten.
' W 'akan muncul lagi dalam sedikit ketika kita ingin mengembalikan kursor ke baris ini.

mw}jdd'wpkJj
  ^

Di sini kita memiliki curly-kanan } yang melompat kursor ke batas paragraf berikutnya; dengan kata lain, ini memindahkan kursor ke baris kosong berikutnya, yaitu baris # 4 dalam contoh kita. (Inilah sebabnya mengapa baris # 4 harus berupa baris kosong; tidak ada spasi, jika tidak } tidak akan menganggapnya sebagai batas.)

mw}jdd'wpkJj
   ^

The j turun satu baris; ini adalah navigasi old-school vi "hjkl". Anda mungkin bisa menggunakan panah bawah di sini juga, saya menemukan "j" agak lebih mudah dibaca, dan lebih mudah digunakan (karena tombol panah tidak selalu di tempat yang sama antara berbagai merek laptop dan keyboard desktop, tetapi "hjkl "Dijamin untuk selalu berada di sisi kanan baris home keyboard QWERTY (yang membantu kecepatan mengetik saya)).
Bagaimanapun, pada titik ini, kursor ada di baris # 5.

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

mw}jdd'wpkJj
    ^^

The dd adalah "garis delete" mengedit perintah, sehingga menghapus baris saat ini, yang merupakan line # 5 dengan "kkk" di atasnya. Menghapus baris juga meletakkannya di buffer tempel default, yang akan kita gunakan exploit untuk membawa "kkk" kembali ke tempat yang kita inginkan di baris # 1, di samping "xxx".

mw}jdd'wpkJj
      ^^

Urutan 'w (single-quote w) melompat kursor kembali ke bookmark kami untuk "w", yang menempatkan kursor pada baris # 1.

mw}jdd'wpkJj
        ^

Huruf kecil "p" PUTS buffer default saat ini (dengan "kkk", seperti yang Anda ingat) setelah kursor. Karena buffer berisi apa yang dulunya baris # 5, file kami secara singkat terlihat seperti ini sekarang:

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

Perhatikan bagaimana "kkk" telah menjadi baris # 2. (Saya tidak bisa dengan mudah menggambarkan di mana kursor pergi ke sana ... itu harus benar-benar berada di awal baris # 2).
Kita sudah dekat tetapi belum sampai di sana ...

mw}jdd'wpkJj
         ^^

The-huruf kecil k hop kursor ke baris # 1 ( "hjkl" navigasi lagi), dan huruf besar J bergabung baris berikutnya ke baris saat ini, membuat file yang terlihat kita seperti ini (kursor masih pada baris # 1, antara the x's & the k's):

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


mw}jdd'wpkJj
           ^

J terakhir adalah navigasi "hjkl" sekali lagi, yang memindahkan kursor ke baris # 2 yang berguna karena itu adalah baris berikutnya yang ingin kita terapkan q .
Bagaimanapun caranya, akan terlihat seperti ini:

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

Jika Anda menekan "q" lagi dan akan terlihat seperti ini (perhatikan kursor ada di baris # 3).

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

Bilas dan ulangi seperlunya. Saya menemukan ini berguna untuk daftar yang lebih panjang karena memungkinkan saya (cukup) tanpa kesulitan membangun kolom.

Ini contoh yang lebih panjang. Menambahkan baris kosong di baris # 7 menyebabkan "ggg" menumpuk pertama di kolom berikutnya. Setelah turun ke "lll", lompat kursor Anda kembali ke baris # 1 (kiri keriting, {, bekerja dengan baik untuk itu) dan teruskan dengan "mmm". Jika Anda memutuskan tidak menyukai cara pengaturannya, tahan u (undo) sebentar dan atur di mana Anda "batas" baris kemudian mulai dari awal.

Ini adalah salah satu hal yang bekerja jauh lebih mudah daripada yang dibutuhkan untuk menjelaskannya. Sementara saya tidak berpikir saya akan menggunakannya untuk bergabung dengan ribuan baris, saya merasa berguna untuk puluhan dan kadang-kadang ratusan.

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

Bagaimana dengan Karakter Ruang Ekstra?
Bagian dari perilaku perintah Join adalah menempatkan spasi di antara garis yang digabungkan.
Jika Anda tidak ingin spasi antara "xxx kkk", Anda dapat
menambahkan perintah delete (x) ke string:

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" membunuh ruang dengan menggunakan x tepat setelah kita menggabungkan dua baris bersama. x dalam mode Navigasi menghapus karakter apa pun yang menjadi tempat kursor berada, yang dalam hal ini adalah karakter spasi yang menyinggung.

"Gabung dg koma" menggantikan ruang dengan koma. Itu sebagian besar sama tetapi kita akan melangkah melalui bagian terakhir yang hanya sedikit berbeda dari contoh sebelumnya.

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

The R menempatkan kita ke dalam mode Edit (khusus modus Ganti, yang akan menimpa karakter apapun dengan apa yang kita ketik).

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

The , secara harfiah jenis koma, yang menimpa ruang menyinggung pada saat itu.

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

Dan kemudian ^ [ memberi sinyal karakter Escape, yang meninggalkan mode Edit dan mengembalikan kita ke mode Navigasi.
Sekarang kita siap untuk j terakhir untuk membawa kita ke baris berikutnya.

Untuk memetakan karakter pelarian Anda perlu menekan ^ Q (windows) atau ^ V (linux & unix) kemudian tekan tombol Esc (jika tidak, karakter Esc akan membatalkan perintah dan kiri Anda bertanya-tanya mengapa peta Anda yang mungkin rumit) definisi hilang begitu saja). Inilah urutan yang harus Anda ketik untuk masuk ke Vim di Windows:

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

Begitu. Mungkin ada banyak cara untuk melakukan hal semacam ini Vim.
Ketika pembatas "field" penting, saya biasanya menempatkan urutan unik sederhana di akhir setiap baris dengan pencarian global dan ganti, lanjutkan dan gabungkan kolom seperti yang saya inginkan dan kemudian ganti-semua untuk mendapatkan pemisah khusus yang saya inginkan .

Bagaimanapun, ini hanyalah satu contoh. Saya harap Anda menganggapnya menarik.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.