formatear en vim para un bonito diseño de columna

126

Tengo este conjunto de datos en un archivo 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

Como puede ver, los números tienen un formato diferente y están desalineados. ¿Hay alguna forma en vim para alinear rápidamente las columnas correctamente, de modo que el resultado sea este

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

Sería genial copiar y pegar secciones con ctrl-v. ¿Alguna pista?

Stefano Borini
fuente

Respuestas:

263

Si utiliza algún tipo de UNIX (Linux, etc.), puede hacer trampa y filtrarlo a través del comando column (1).

:%!column -t

Lo anterior se analizará en delimitadores dentro de literales de cadena que es incorrecto, por lo que probablemente necesitará pasos de procesamiento previo y especificar el delimitador para este archivo, por ejemplo:

%!sed 's/","/\&/' | column -t -s '&'
soleado256
fuente
1
Genial comando, no estaba al tanto de ello (habiendo escrito un script perl personalizado para hacer ese tipo de operación en el pasado).
hlovdal
24
Debido a que mis archivos no tenían un espacio que tuve que usar :%!column -t -s ','. Elimina las comas, por lo que ya no son técnicamente archivos csv. Pero los arregla maravillosamente, que es lo que necesitaba.
Eduardo
27
Gran consejo! Solo agregando, también funciona para la selección visual con:'<,'>!column -t
freitass
2
¿Alguien sabe de una solución para trabajar con columnas citadas con comas en la columna? ejemplo "2151 Main ST Houston, TX"
metrix
3
@metrix, aquí hay una solución muy torpe: 1) convierta los espacios dentro de los delimitadores en un carácter diferente, 2) luego ejecute columncomo se describe en la publicación, 3) luego reemplace sus delimitadores de nuevo a espacios. Un comando de ejemplo en modo visual para el paso 1 es:'<,'>s/"\(\w\+\) \(\w\+\)"/"\1_\2"/g
Luciano
54

A veces queremos alinear solo dos columnas. En ese caso, no necesitamos ningún complemento y podemos usar la funcionalidad de Vim pura como esta:

  1. Elige un separador. En la publicación de OP, esta es una coma, en mi ejemplo, esto es =.
  2. Agregue espacios antes / después. Yo uso s/=/= ...spaces... /en la selección visual para esto.
  3. Localice la palabra más larga y coloque el cursor después de ella.
  4. Elimine todo el espacio en blanco adicional usando dwun movimiento vertical.

Ejemplo de esta técnica demostrada a continuación:

Ejemplo

No necesito alinear las cosas con la frecuencia suficiente para instalar otro complemento, por lo que esta fue mi forma preferida de lograrlo, especialmente porque no requiere mucho pensamiento.

rr-
fuente
44
¿Cómo hiciste ese lindo gif?
Stefano Borini
1
blog.bahraniapps.com/gifcam desafortunadamente, parece que es una herramienta solo para Windows.
rr
Cuando terminó de alinear la parte superior, ¿cómo movió el cursor al centro de la pantalla y luego comenzó a alinear la parte inferior?
cychoi
55
Después :s/=/ =/es mucho mejor usar Ctrl + Vpara seleccionar la columna derecha, luego alinearla usando <<y .para repetir. Lo encontré aquí: stackoverflow.com/a/24704379/2152384
pozitron57
1
O cree una macro para hacer el trabajo @ pozitron57
Arthur Julião
24

Como sugirió sunny256, el columncomando es una excelente forma de hacerlo en máquinas Unix / Linux, pero si desea hacerlo en Vim puro (para que también se pueda usar en Windows), la forma más fácil es instalar Align plugin y luego hacer:

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

La primera línea alinea las entradas en las comas y la segunda mueve la coma para que esté alineada con el valor anterior. Es posible que pueda usar AlignCtrlpara definir un mapeo personalizado que haga todo de una vez, pero nunca puedo recordar cómo usarlo ...

Editar

Si no le importa dos espacios entre las entradas y desea hacer esto en un comando, también puede hacer:

:%Align ,\zs
DrAl
fuente
Funciona perfectamente en una tabla LaTeX::'<,'>Align &
Thomas
También se puede lograr con :%Align! lP0 \s( l= alineado a la izquierda, P0= 0 relleno después del separador).
ntd
8

Esta es una gran respuesta usando macros vim: https://stackoverflow.com/a/8363786/59384 : básicamente, comienza a grabar una macro, formatea la primera columna, detiene la grabación y luego repite la macro para todas las líneas restantes.

Copia / pegado de esa respuesta:

qa0f:w100i <Esc>19|dwjq4@a

Tenga en cuenta el espacio único después del 100i, y <Esc> significa "presione escape" - no escriba "<Esc>" literalmente.

Traducción:

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)
zcrar70
fuente
7

Ahora también tenemos el fabuloso complemento EasyAlign , escrito por junegunn.

Demostración GIF de su archivo README:

rr-
fuente
4

Puede usar el complemento csv.vim .

:%ArrangeColumn

Sin embargo, esto no hará exactamente lo que ha pedido: ajustará correctamente el contenido de las celdas, mientras que tiene sus valores alineados por el punto decimal o por el primer dígito.

El complemento tiene muchos otros comandos útiles para trabajar con archivos CSV.

Daan
fuente
3

Además, si tiene columnas muy largas, puede ser útil desactivar el ajuste predeterminado

: establecer nowrap
:%! columna -t

(tenga en cuenta que en Debian también tiene una opción adicional para la columna -n, que si desea dividir varios delimitadores adyacentes)

Amos Folarin
fuente
mucho mejor con nowrap. Incluí su sugerencia, gracias 'CSV comando establecido nowrap | %! column -t -s ',' '.
Peruz
Además, tenga en cuenta la opción -n para deshabilitar la fusión de columnas vacías. stackoverflow.com/questions/1875305/command-line-csv-viewer
Peruz
3

Acabo de escribir tablign para este propósito. Instalar con

pip3 install tablign --user

Luego simplemente marque la tabla en vim y haga

:'<,'>:!tablign

ingrese la descripción de la imagen aquí

Nico Schlömer
fuente
1

Pregunta bastante antigua, pero recientemente aproveché un excelente complemento vim que permite el formateo de tablas sobre la marcha o después de los hechos (según lo requiera su caso de uso):

https://github.com/dhruvasagar/vim-table-mode

Alicia
fuente
1

Aquí hay una respuesta de script Vim pura, sin complementos, sin macros:

Puede ser más claro comenzar con la solución de mi problema como ejemplo. Seleccioné las líneas de código que quería afectar, luego usé el siguiente comando (recuerde que ingresar al modo de comando desde el modo visual antepone automáticamente el "'<,'>", por lo que actúa en el rango visual):

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

Excepto que en realidad NO escribí "<0d>". Puede ingresar caracteres no imprimibles en la línea de comando presionando ctrl-v, luego la tecla que desea escribir. "<0d>" es lo que se muestra en la línea de comando después de escribir 'ctrl-v enter'. Aquí, se analiza mediante el comando "normal" como la salida del modo de búsqueda "/". El cursor salta a "valor" en la línea actual.

Luego simplemente [D] elegimos el resto de la línea, saltamos a la columna 70 (o lo que sea que necesite en su caso), y [P] ut lo que acabamos de eliminar. Esto significa que tenemos que determinar el ancho de la línea más ancha, hasta nuestra búsqueda. Si no ha puesto esa información en su línea de estado, puede ver la columna del cursor ingresando el comando de modo normal 'g ctrl-g'. También tenga en cuenta que saltar a una columna que no existe requiere la configuración 'virtualedit'.

Dejé el término de búsqueda para el comando: g (lobal) vacío, ya que usamos un bloque visual y queríamos afectar a cada línea, pero puede dejarlo usando una selección visual (y el '' <, '> ") y poner un término de búsqueda allí en su lugar. O combine una selección visual y un término de búsqueda para limitar las cosas con mayor precisión / facilidad.

Esto es algo que aprendí recientemente: si comete un error en un comando de modo de comando complejo, deshaga con 'u' (si afectó al búfer), luego presione “q:” para ingresar un búfer de historial de comandos especial que actúa de manera muy similar a un búfer convencional . Edite cualquier línea y presione Intro, y el comando modificado se ingresa como un nuevo comando. Indispensable si no quieres tener que preocuparte por formular todo perfectamente la primera vez.

atimholt
fuente
0

Escribí una secuencia de comandos de Python que permite a los usuarios hacer una columna básica de cualquier tipo de texto también fuera de vim. No estoy seguro de si esto funcionará para usuarios de Windows o Mac.

columnice.py gist

Uso en vim.

:'<,'>!columnice =

Esto usará el signo igual como el delímetro. Sin embargo, el delímetro no se tira.

Bassim Huis
fuente
0

Tengo esto en mi .vimrc.

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

Esto alinea las columnas manteniendo la coma, que puede ser necesaria más adelante para una lectura correcta. Por ejemplo, con Python Pandas read_csv(..., skipinitialspace=True), gracias a los chicos de Pandas por esta opción inteligente, de lo contrario en vim %s/,\s\+/,/g. Puede ser más fácil si columntiene la opción : separador de salida , supongo, mi no y no estoy seguro de por qué (mi página de manual para la columna dice 2004, en ubuntu 18.04, no estoy seguro de que ubuntu obtenga una nueva versión) . De todos modos, esto funciona para mí, y comenta si tienes alguna sugerencia.

Peruz
fuente