Vim: incollare le righe riga per riga


8

Supponiamo di avere un file contenente:

xxx
yyy
zzz

e un altro file:

kkk
qqq
ppp

Voglio ottenere:

xxxkkk
yyyqqq
zzzppp

È possibile in Vim con qualche comando? (Ho provato a utilizzare VISUAL BLOCK ma senza successo).

Nel mio caso particolare ho due file di grandi dimensioni con molte righe da incollare, quindi la risposta potrebbe anche essere un comando shell ma vorrei sapere se c'è un modo per farlo anche all'interno dello stesso file.

Risposte:


12

Dalla riga di comando, puoi provare

paste -d '\0' file1 file2 > file3

Questo fa esattamente quello che vuoi.

Anche la modalità Visual Block in vimè perfettamente adatta a questo compito. Sei sicuro di averlo fatto correttamente? Dovresti

  • Passa alla modalità blocco visivo
  • Seleziona il testo e premi yper strappare
  • Vai all'altro file, nell'angolo in alto a sinistra del per essere incollare i dati (ultimo x) e premere p.

Stavo incollando in Visual Block ... questo è esattamente quello che volevo fare. Grazie.
Fabio F.

1
Almeno con GNU Coreutils, paste -d '' ...funziona anche. È interessante notare che la manpage e le pagine informative di coreutils sembrano non documentare '\ 0', anche se è specificato nelle specifiche Unix singole.
derobert,

5

Puoi farlo direttamente durante la modifica file1. Digitare :per passare a command modein vim. Quindi digitare:

%!paste -d '' - file2

3

Ecco un modo per farlo all'interno dello stesso file usando solo Vim.

Implica una mappatura dei tasti. L'ho pensato una volta quando volevo organizzare diversi elenchi in strutture simili a tabelle in un testo semplice.

Questo si basa sul tasto } (parentesi graffa destra) per saltare i limiti di paragrafo. (Le parentesi graffe sono speculari, a proposito: { salta all'inizio del file e } verso la fine.)

Quindi ... supponiamo di avere un file di dati come questo (questo suppone che la riga # sia attivata con : set nu ):

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

È importante che la riga 4 sia una riga vuota (senza spazi bianchi), spiegherò perché tra un momento.

Eseguire il comando della mappa seguente
:: map q mw} jdd'wpkJj

Questo associa il tasto "q" a un programma a 12 caratteri, che analizzerò in dettaglio di seguito.

Quando premi "q" eseguirà quel programma; si noti che il cursore, che è iniziato sulla riga # 1 è ora sulla riga successiva, pronto a premere nuovamente "q". Forse avrai notato che c'è un carattere spaziale tra "xxx kkk"; se non lo desideri, vedi "Che ne dici di The Extra Space Character?" sotto, verso la fine.

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

Ecco una ripartizione della mappatura:

   :map q mw}jdd'wpkJj
   ^

I due punti ti portano in modalità comando in modo che possiamo emettere il comando "map".

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

map q lega q con la seguente sequenza di caratteri. Nota che "q" è solo la mia solita chiave "mappa su"; puoi usare altri tasti. Per impostazione predefinita, la minuscola q è mappata per avviare la registrazione macro; poiché uso raramente (mai?) che trovo "q" più utile per le macro di utilità una tantum. Puoi anche usare Q maiuscola (ad es. Mappa Q) o un tasto fnct o così via.

Ora ogni volta che premi "q" (in modalità navigazione), vim eseguirà questa serie di sequenze di tasti:

   mw}jdd'wpkJj

Che ovviamente sembra totalmente incomprensibile, quindi lo analizzerò azione per azione (con ^^ di seguito) per rendere più facile seguire ciò che sta accadendo.

mw}jdd'wpkJj
^^

Il mw contrassegna una posizione denominata, il nome qui è 'w'. Uso "w" per impostazione predefinita (lo considero come la mia "posizione di lavoro". Qualsiasi posizione denominata, da az funzionerebbe, a condizione che tu sia coerente.
La "w" verrà visualizzata di nuovo tra un po 'quando vuole riportare il cursore su questa riga.

mw}jdd'wpkJj
  ^

Qui abbiamo il ricciolo a destra } che salta il cursore fino al limite del paragrafo successivo; in altre parole, questo sposta il cursore sulla riga vuota successiva, che è la linea # 4 nel nostro esempio. (Questo è il motivo per cui la linea n. 4 dovrebbe essere una linea vuota; nessuno spazio bianco, altrimenti } non la considererà un limite.)

mw}jdd'wpkJj
   ^

La j scende di una riga; questa è la navigazione vi "hjkl" della vecchia scuola. Probabilmente potresti usare anche una freccia giù qui, trovo "j" un po 'più facile da leggere e più facile da usare (perché i tasti freccia non sono sempre nello stesso posto tra varie marche di tastiere per laptop e desktop, ma "hjkl "è garantito per essere sempre sul lato destro della riga iniziale di qualsiasi tastiera QWERTY (il che aiuta la mia velocità di battitura)).
Ad ogni modo, a questo punto, il cursore si trova sulla linea # 5.

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

mw}jdd'wpkJj
    ^^

Il dd è il comando Modifica "linea di eliminazione", quindi cancella la linea corrente, che è la linea # 5 con il "KKK" su di esso. L'eliminazione della riga la inserisce anche nel buffer di incollaggio predefinito, che utilizzeremo exploit per riportare "kkk" nel punto desiderato nella riga 1, accanto a "xxx".

mw}jdd'wpkJj
      ^^

La sequenza 'w (virgoletta singola w) riporta il cursore sul nostro segnalibro per "w", che posiziona il cursore sulla riga # 1.

mw}jdd'wpkJj
        ^

La "p" minuscola Mette il buffer predefinito corrente (con "kkk", come ricorderete) dopo il cursore. Poiché il buffer contiene quella che era la riga 5, il nostro file appare brevemente come questo ora:

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

Nota come "kkk" è diventato la linea # 2. (Non riesco a illustrare facilmente dove si trova il cursore ... dovrebbe essere davvero all'inizio della riga # 2).
Siamo vicini ma non ancora del tutto ...

mw}jdd'wpkJj
         ^^

La lettera minuscola k sposta il cursore fino alla riga # 1 (navigazione "hjkl" di nuovo), e la J maiuscola unisce la riga successiva alla riga corrente, facendo apparire il nostro file in questo modo (il cursore è ancora sulla riga # 1, tra le x e le k):

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


mw}jdd'wpkJj
           ^

L'ultimo j è ancora una volta la navigazione "hjkl", che sposta il cursore verso il basso sulla riga # 2 che è utile perché quella è la riga successiva a cui vogliamo applicare q .
Ad ogni modo, sarà simile a questo:

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

Se premi di nuovo "q" e sembrerà così (nota che il cursore è sulla linea # 3).

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

Risciacquare e ripetere se necessario. Lo trovo utile per elenchi più lunghi perché mi consente (abbastanza) di costruire colonne senza dolore.

Ecco un esempio più lungo. L'aggiunta di una riga vuota alla riga n. 7 fa sì che "ggg" si impili per primo nella colonna successiva. Dopo essere sceso a "lll", sposta il cursore indietro fino alla riga # 1 (a sinistra ricciolo, {, funziona bene per quello) e continua con "mmm". Se decidi che non ti piace il modo in cui sta organizzando, tieni premuto su u (annulla) per un po 'e modifica dove si trova la tua linea di "confine" quindi ricomincia.

Questa è una di quelle cose che funzionano molto più facilmente di quanto ci voglia uno sforzo per spiegare. Anche se non credo che lo userei per unire migliaia di righe, lo trovo utile per dozzine e occasionalmente centinaia.

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

Che dire del personaggio extra spazio?
Parte del comportamento del comando Unisci è che inserisce uno spazio tra le linee a cui si unisce.
Se non vuoi uno spazio tra "xxx kkk" puoi
aggiungere un comando di cancellazione (x) alla stringa:

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" uccide lo spazio usando la x subito dopo aver unito le due linee insieme. x in modalità Navigazione cancella qualunque carattere si trovi sul cursore, che in questo caso era il carattere spaziale offensivo.

Il "join w / virgola" sostituisce lo spazio con una virgola. Questo è principalmente lo stesso, ma passeremo all'ultima parte che è solo un po 'diversa dall'esempio precedente.

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

La R ci mette in modalità Modifica (in particolare la modalità Sostituisci, che sovrascriverà tutti i caratteri con ciò che digitiamo).

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

Il , letteralmente tipi una virgola, che è sovrascrive lo spazio offendere a quel punto.

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

E poi ^ [ segnala un carattere Escape, che lascia la modalità Edit e ci riporta in modalità Navigation.
Ora siamo pronti per la j finale per portarci alla riga successiva.

Per mappare un carattere di escape devi premere ^ Q (windows) o ^ V (linux e unix) quindi premi il tasto Esc (in caso contrario, il carattere Esc interromperà il comando e la tua sinistra si chiederà perché la tua mappa forse complessa definizione appena svanita). Ecco la sequenza che dovresti digitare per farlo entrare in Vim su Windows:

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

Così. Probabilmente ci sono dozzine di modi per fare questo genere di cose Vim.
Quando i delimitatori "di campo" contano, di solito inserisco una semplice sequenza unica alla fine di ogni riga con ricerca globale e sostituisci, vado avanti e unisco le colonne come voglio e poi sostituisco tutto per ottenere i separatori specifici che desidero .

Comunque, questo è solo un esempio. Spero che l'abbia trovato interessante.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.