riformattare in vim per un bel layout di colonna


126

Ho questo set di dati in un file CSV

1.33570301776, 3.61194e-06, 7.24503e-06, -9.91572e-06, 1.25098e-05, 0.0102828, 0.010352, 0.0102677, 0.0103789, 0.00161604, 0.00167978, 0.00159998, 0.00182596, 0.0019804, 0.0133687, 0.010329, 0.00163437, 0.00191202, 0.0134425 
1.34538754675, 3.3689e-06, 9.86066e-06, -9.12075e-06, 1.18058e-05, 0.00334344, 0.00342207, 0.00332897, 0.00345504, 0.00165532, 0.00170412, 0.00164234, 0.00441903, 0.00459294, 0.00449357, 0.00339737, 0.00166596, 0.00451926, 0.00455153
1.34808186291, -1.99011e-06, 6.53026e-06, -1.18909e-05, 9.52337e-06, 0.00158065, 0.00166529, 0.0015657, 0.0017022, 0.000740644, 0.00078635, 0.000730052, 0.00219736, 0.00238191, 0.00212762, 0.00163783, 0.000750669, 0.00230171, 0.00217917

Come puoi vedere, i numeri sono formattati in modo diverso e disallineati. Esiste un modo per allineare rapidamente le colonne correttamente, in modo che il risultato sia questo

1.33570301776,  3.61194e-06, 7.24503e-06, -9.91572e-06, 1.25098e-05, 0.0102828,  0.010352,   0.0102677,  0.0103789, 0.00161604, 0.00167978, 0.00159998, 0.00182596, 0.0019804,  0.0133687,  0.010329,   0.00163437, 0.00191202, 0.0134425 
1.34538754675,  3.3689e-06,  9.86066e-06, -9.12075e-06, 1.18058e-05, 0.00334344, 0.00342207, 0.00332897, 0.00345504,0.00165532, 0.00170412, 0.00164234, 0.00441903, 0.00459294, 0.00449357, 0.00339737, 0.00166596, 0.00451926, 0.00455153
1.34808186291, -1.99011e-06, 6.53026e-06, -1.18909e-05, 9.52337e-06, 0.00158065, 0.00166529, 0.0015657,  0.0017022, 0.000740644,0.00078635, 0.000730052,0.00219736, 0.00238191, 0.00212762, 0.00163783, 0.000750669,0.00230171, 0.00217917

Sarebbe fantastico copiare e incollare sezioni con ctrl-v. Qualche suggerimento?

Risposte:


263

Se utilizzi un tipo di UNIX (Linux, ecc.), Puoi imbrogliare e filtrarlo tramite il comando column (1).

:%!column -t

Quanto sopra analizzerà i delimitatori all'interno dei valori letterali delle stringhe che sono errati, quindi probabilmente avrai bisogno di fasi di pre-elaborazione e specificando il delimitatore per questo file ad esempio:

%!sed 's/","/\&/' | column -t -s '&'

1
Ottimo comando, non ne ero a conoscenza (avendo scritto script perl personalizzati per fare quel tipo di operazione in passato).
hlovdal

24
Perché i miei file non avevano uno spazio che dovevo usare :%!column -t -s ','. Rimuove le virgole, quindi non sono più file CSV tecnici. Ma li organizza magnificamente, che è quello di cui avevo bisogno.
Eduardo,

27
Ottimo consiglio! Solo aggiungendo, funziona anche per la selezione visiva con:'<,'>!column -t
freitass

2
Qualcuno sa di una soluzione per lavorare con colonne tra virgolette con virgole nella colonna? esempio "2151 Main ST Houston, TX"
metrix

3
@metrix, ecco una soluzione molto goffa: 1) converti gli spazi all'interno dei delimitatori in un carattere diverso, 2) quindi esegui columncome descritto nel post, 3) quindi rimetti i tuoi delimitatori negli spazi. Un comando di esempio in modalità visiva per il passaggio n. 1 è:'<,'>s/"\(\w\+\) \(\w\+\)"/"\1_\2"/g
Luciano,

54

A volte vogliamo allineare solo due colonne. In tal caso, non abbiamo bisogno di alcun plug-in e possiamo usare la funzionalità Vim pura come questa:

  1. Scegli un separatore. Nel post di OP questa è una virgola, nel mio esempio questo è =.
  2. Aggiungi spazi prima / dopo. Uso s/=/= ...spaces... /la selezione visiva per questo.
  3. Individua la parola più lunga e posiziona il cursore dopo di essa.
  4. Rimuovi tutto lo spazio extra usando dwe il movimento verticale.

Esempio di questa tecnica dimostrato di seguito:

Esempio

Non mi trovo a dover allineare le cose abbastanza spesso per installare un altro plugin, quindi questo è stato il mio modo preferito di realizzarlo - soprattutto che non richiede molto pensiero.


4
Come hai fatto quella bella gif?
Stefano Borini,

1
blog.bahraniapps.com/gifcam purtroppo sembra uno strumento solo per Windows.
r-

Quando hai finito di allineare la parte superiore, come hai spostato il cursore al centro dello schermo e poi hai iniziato ad allineare la parte inferiore?
cychoi,

5
Dopo :s/=/ =/è molto meglio usare Ctrl + Vper selezionare la colonna di destra, quindi allinearla usando <<e .per ripetere. Trovato qui: stackoverflow.com/a/24704379/2152384
pozitron57

1
Oppure crea una macro per fare il lavoro @ pozitron57
Arthur Julião,

24

Come suggerito sunny256, il columncomando è un ottimo modo per farlo su macchine Unix / Linux, ma se vuoi farlo in puro Vim (in modo che possa essere usato anche in Windows), il modo più semplice è installare Align plugin e poi fai:

:%Align ,
:%s/\(\s\+\),\s/,\1/g

La prima riga allinea le voci sulle virgole e la seconda sposta la virgola in modo che sia a filo con il valore precedente. Potresti essere in grado di utilizzare AlignCtrlper definire una mappatura personalizzata che fa l'intero lotto in una sola volta, ma non riesco mai a ricordare come usarlo ...

modificare

Se non ti dispiace due spazi tra le voci e vuoi farlo in un solo comando, puoi anche fare:

:%Align ,\zs

Funziona perfettamente in un tavolo LaTeX::'<,'>Align &
Thomas,

Può essere realizzato anche con :%Align! lP0 \s( l= allineato a sinistra, P0= 0 riempimento dopo il separatore).
ntd

8

Questa è un'ottima risposta usando le macro di vim: https://stackoverflow.com/a/8363786/59384 - in pratica, inizi a registrare una macro, formatta la prima colonna, interrompi la registrazione e ripeti la macro per tutte le righe rimanenti.

Copia / incollato da quella risposta:

qa0f:w100i <Esc>19|dwjq4@a

Nota il singolo spazio dopo la 100i e <Esc> significa "premere escape" - non digitare "<Esc>" letteralmente.

Traduzione:

qa         -- record macro in hotkey a
0          -- go to beginning of line
f:         -- go to first : symbol
w          -- go to next non-space character after the symbol
100i <Esc> -- insert 100 spaces
19|        -- go to 19th column (value 19 figured out manually)
dw         -- delete spaces until : symbol
j          -- go to next line
q          -- stop recording macro
4@a        -- run the macro 4 times (for the remaining 4 lines)


7

Ora abbiamo anche il favoloso plug-in EasyAlign , scritto da Junegunn.

Dimostrazione GIF dal suo README:


4

È possibile utilizzare il plug-in csv.vim .

:%ArrangeColumn

Tuttavia, questo non farà esattamente quello che ti è stato chiesto: regolerà correttamente il contenuto delle celle, mentre i tuoi valori saranno allineati con il punto decimale o con la prima cifra.

Il plugin ha molti altri comandi utili per lavorare con i file CSV.


3

anche se hai colonne molto lunghe può essere utile disabilitare il wrapping predefinito

: imposta nowrap
:%! colonna -t

(nota in debian hai anche un'ulteriore opzione per la colonna -n che se vuoi dividere più delimitatori adiacenti)


molto meglio con nowrap. Ho incluso il tuo suggerimento, grazie al comando CSV set nowrap | %! column -t -s ',' `.
Peruz,

inoltre, notare l'opzione -n ​​per disabilitare l'unione di colonne vuote. stackoverflow.com/questions/1875305/command-line-csv-viewer
Peruz

3

Ho appena scritto tablign per questo scopo. Installa con

pip3 install tablign --user

Quindi segna semplicemente la tabella in vim e fai

:'<,'>:!tablign

inserisci qui la descrizione dell'immagine



1

Ecco una risposta allo script Vim puro, nessun plug-in, nessuna macro:

Potrebbe essere più chiaro iniziare con la soluzione del mio problema come esempio. Ho selezionato le righe di codice che volevo influenzare, quindi ho usato il seguente comando (ricordate che l'accesso alla modalità di comando dalla modalità visiva antepone automaticamente “'<,'>”, quindi agisce sul campo visivo):

:'<,'>g``normal / "value<0d>D70|P`

Tranne il fatto che NON ho effettivamente digitato "<0d>". È possibile inserire caratteri non stampabili sulla riga di comando premendo ctrl-v, quindi il tasto che si desidera digitare. "<0d>" è ciò che viene visualizzato sulla riga di comando dopo aver digitato 'ctrl-v invio'. Qui, viene analizzato dal comando "normale" come uscita dalla modalità di ricerca "/". Il cursore passa quindi al "valore" nella riga corrente.

Quindi semplicemente [D] elimina il resto della riga, passa alla colonna 70 (o qualsiasi altra cosa di cui hai bisogno nel tuo caso) e [P] ut quello che abbiamo appena eliminato. Ciò significa che dobbiamo determinare la larghezza della linea più ampia, fino alla nostra ricerca. Se non hai inserito tali informazioni nella tua statusline, puoi vedere la colonna del cursore inserendo il comando in modalità normale 'g ctrl-g'. Nota anche che saltare a una colonna che non esiste richiede l'impostazione 'virtualedit'!

Ho lasciato vuoto il termine di ricerca per il comando: g (lobal), poiché abbiamo usato un blocco visivo e volevamo influenzare ogni linea, ma puoi lasciarlo usando una selezione visiva (e il '' <, '> ”) e mettere un termine di ricerca lì invece. Oppure combina una selezione visiva e un termine di ricerca per restringere le cose in modo più fine / semplice.

Ecco qualcosa che ho imparato di recente: se sbagli su un comando in modalità comando complesso, annulla con 'u' (se influisce sul buffer), quindi premi "q:" per inserire un buffer della cronologia dei comandi speciale che si comporta in modo molto simile a un buffer convenzionale . Modifica qualsiasi riga e premi invio e il comando modificato viene inserito come nuovo comando. Indispensabile se non vuoi stressarti a formulare tutto perfettamente la prima volta.


0

Ho scritto uno script in Python che consente agli utenti di scrivere in modo basilare qualsiasi tipo di testo anche al di fuori di VIM. Non sono sicuro se questo funzionerà per utenti Windows o Mac.

columnice.py gist

Utilizzo in vim.

:'<,'>!columnice =

Questo utilizzerà il segno di uguale come delimitatore. Il delimitatore non viene gettato via però.


0

Ho questo nel mio .vimrc.

command! CSV set nowrap | %s/,/,|/g | %!column -n -t -s "|" 

Ciò allinea le colonne mantenendo la virgola, che potrebbe essere necessaria in seguito per una lettura corretta. Ad esempio, con i Panda di Python read_csv(..., skipinitialspace=True), grazie ai ragazzi di Panda per questa opzione intelligente, altrimenti in vim %s/,\s\+/,/g. Potrebbe essere più semplice se hai columnl'opzione --output-separator credo, il mio no e non sono sicuro del perché (la mia pagina man per la colonna dice 2004, su Ubuntu 18.04, non sono sicuro che Ubuntu otterrà una nuova versione) . Ad ogni modo, questo funziona per me e commenta se hai qualche suggerimento.

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.