reformate no vim para um bom layout de coluna

126

Eu tenho esse conjunto de dados em um arquivo 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 você pode ver, os números são formatados de maneira diferente e desalinhados. Existe uma maneira no vim de alinhar rapidamente as colunas corretamente, para que o resultado seja 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

Seria ótimo copiar e colar seções com ctrl-v. Alguma dica?

Stefano Borini
fonte

Respostas:

263

Se você usa algum tipo de UNIX (Linux, etc), pode trapacear e filtrá-lo através do comando da coluna (1).

:%!column -t

O acima será analisado em delimitadores dentro de literais de string, o que está errado; portanto, você provavelmente precisará de etapas de pré-processamento e a especificação do delimitador para este arquivo, por exemplo:

%!sed 's/","/\&/' | column -t -s '&'
sunny256
fonte
1
Comando legal, eu não sabia disso (depois de escrever um script perl personalizado para fazer esse tipo de operação no passado).
hlovdal 4/08/09
24
Porque meus arquivos não tinham um espaço que eu tinha que usar :%!column -t -s ','. Ele remove as vírgulas, para que não sejam mais arquivos csv técnicos. Mas organiza-os lindamente, e era disso que eu precisava.
Eduardo
27
Ótima dica! Basta adicionar, ele funciona para seleção visual também com:'<,'>!column -t
freitass
2
Alguém sabe de uma solução para trabalhar com colunas citadas com vírgulas na coluna? exemplo "2151 Main ST Houston, TX"
metrix 30/12/2013
3
@ Metrix, aqui está uma solução muito desajeitada: 1) converta espaços dentro dos delimitadores em um caractere diferente; 2) execute columncomo descrito no post; 3) substitua os delimitadores de volta aos espaços. Um exemplo de comando no modo visual para a etapa 1 é:'<,'>s/"\(\w\+\) \(\w\+\)"/"\1_\2"/g
Luciano
54

Às vezes, queremos alinhar apenas duas colunas. Nesse caso, não precisamos de plugins e podemos usar a funcionalidade pura do Vim como esta:

  1. Escolha um separador. No post do OP, esta é uma vírgula, no meu exemplo, isso é =.
  2. Adicione espaços antes / depois. Eu uso s/=/= ...spaces... /na seleção visual para isso.
  3. Localize a palavra mais longa e coloque o cursor depois dela.
  4. Remova todo o espaço em branco extra usando dwe movimento vertical.

Exemplo desta técnica demonstrada abaixo:

Exemplo

Não estou precisando alinhar as coisas com frequência suficiente para instalar outro plug-in, então essa foi a minha maneira preferida de realizá-lo - especialmente porque não requer muita reflexão.

rr-
fonte
4
Como você fez esse belo gif?
Stefano Borini
1
blog.bahraniapps.com/gifcam , infelizmente, parece ser uma ferramenta apenas para Windows.
RR
Quando você terminou de alinhar a parte superior, como moveu o cursor para o meio da tela e começou a alinhar a parte inferior?
cychoi
5
Depois :s/=/ =/que for muito melhor usar Ctrl + Vpara selecionar a coluna direita, alinhe-a usando <<e .para repetir. Encontrei aqui: stackoverflow.com/a/24704379/2152384
pozitron57
1
Ou creaete uma macro para fazer de trabalho @ pozitron57
Arthur Julião
24

Como sunny256 sugeriu, o columncomando é uma ótima maneira de fazer isso em máquinas Unix / Linux, mas se você quiser fazê-lo em Vim puro (para que também possa ser usado no Windows), a maneira mais fácil é instalar o Align plugin e faça:

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

A primeira linha alinha as entradas nas vírgulas e a segunda move a vírgula para que fique nivelada com o valor anterior. Você pode usar AlignCtrlpara definir um mapeamento personalizado que faz todo o lote de uma só vez, mas nunca me lembro como usá-lo ...

Editar

Se você não se importa com dois espaços entre as entradas e deseja fazer isso em um comando, também pode:

:%Align ,\zs
DrAl
fonte
Funciona perfeitamente em uma tabela LaTeX::'<,'>Align &
Thomas
Pode ser realizado também com :%Align! lP0 \s( l= alinhado à esquerda, P0= 0 preenchimento após o separador).
ntd 01/02
8

Esta é uma ótima resposta usando as macros do vim: https://stackoverflow.com/a/8363786/59384 - basicamente, você começa a gravar uma macro, formata a primeira coluna, para de gravar e repita a macro para todas as linhas restantes.

Copie / cole essa resposta:

qa0f:w100i <Esc>19|dwjq4@a

Observe o espaço único após o 100i e <Esc> significa "pressione escape" - não digite "<Esc>" literalmente.

Tradução:

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
fonte
7

Agora também temos o fabuloso plugin EasyAlign , escrito por junegunn.

GIF de demonstração do seu README:

rr-
fonte
4

Você pode usar o plugin csv.vim .

:%ArrangeColumn

No entanto, isso não fará exatamente o que você pediu: ele ajustará corretamente o conteúdo das células, enquanto você tem seus valores alinhados pelo ponto decimal ou pelo primeiro dígito.

O plug-in tem muitos outros comandos úteis para trabalhar com arquivos CSV.

Daan
fonte
3

Além disso, se você tiver colunas muito longas, pode ser útil desativar o agrupamento padrão

: definir nowrap
:%! coluna -t

(observe no debian você também tem uma opção adicional para a coluna -n que, se você quiser dividir vários delimitadores adjacentes)

Amos Folarin
fonte
muito melhor com nowrap. Eu incluí sua sugestão, obrigado 'comando CSV set nowrap | %! coluna -t -s ',' '.
Peruz 2/01
Além disso, observe a opção -n para desativar a mesclagem de colunas vazias. stackoverflow.com/questions/1875305/command-line-csv-viewer
Peruz
3

Acabei de escrever tablign para esse fim. Instale com

pip3 install tablign --user

Em seguida, basta marcar a tabela no vim e fazer

:'<,'>:!tablign

insira a descrição da imagem aqui

Nico Schlömer
fonte
1

Pergunta bastante antiga, mas recentemente me vali de um excelente plug-in vim que permite a formatação de tabelas em tempo real ou após o fato (conforme o caso de uso):

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

Alice
fonte
1

Aqui está uma resposta de script pura do Vim, sem plugins, sem macros:

Pode ser mais claro começar com a solução do meu problema como exemplo. Selecionei as linhas de código que gostaria de afetar e, em seguida, usei o seguinte comando (lembre-se de que entrar no modo de comando a partir do modo visual precede automaticamente o “'<,'>”, para que ele atue no alcance visual):

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

Exceto que eu NÃO digitei "<0d>". Você pode inserir caracteres não imprimíveis na linha de comando pressionando ctrl-v e, em seguida, a tecla que deseja digitar. "<0d>" é o que é renderizado na linha de comando depois que eu digitei 'ctrl-v enter'. Aqui, ele é analisado pelo comando "normal" como a saída do modo de pesquisa "/". O cursor então pula para "valor" na linha atual.

Depois, simplesmente [D] excluímos o restante da linha, pulamos para a coluna 70 (ou o que você precisar no seu caso) e [P] ut o que acabamos de excluir. Isso significa que precisamos determinar a largura da linha mais larga, até a nossa pesquisa. Se você não colocou essas informações na sua linha de status, pode ver a coluna do cursor digitando o comando no modo normal 'g ctrl-g'. Observe também que saltar para uma coluna que não existe requer a configuração 'virtualedit'!

Deixei o termo de pesquisa para o comando: g (lobal) vazio, pois usamos um bloco visual e queríamos afetar todas as linhas, mas você pode deixar de usar uma seleção visual (e o '' <, '> ") e colocar um termo de pesquisa lá. Ou combine uma seleção visual e um termo de pesquisa para restringir as coisas de maneira mais fina / fácil.

Aqui está uma coisa que aprendi recentemente: se você errar em um comando complexo do modo de comando, desfaça com 'u' (se isso afetou o buffer) e pressione “q:” para inserir um buffer especial do histórico de comandos que funciona como um buffer convencional . Edite qualquer linha e pressione enter, e o comando alterado é inserido como um novo comando. Indispensável se você não quiser se estressar ao formular tudo perfeitamente da primeira vez.

atimholt
fonte
0

Eu escrevi um script python que permite que os usuários columiem basicamente qualquer tipo de texto também fora do vim. Não tenho certeza se isso funcionará para usuários do Windows ou Mac.

columnice.py gist

Uso quando estiver no vim.

:'<,'>!columnice =

Isso usará o sinal de igual como o delímetro. O delimitador não é jogado fora.

Bassim Huis
fonte
0

Eu tenho isso no meu .vimrc.

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

Isso alinha as colunas enquanto mantém a vírgula, que pode ser necessária posteriormente para a leitura correta. Por exemplo, com o Python Pandas read_csv(..., skipinitialspace=True), agradeço aos Pandas por essa opção inteligente, caso contrário no vim %s/,\s\+/,/g. Pode ser mais fácil se você columntiver a opção --output-separator, eu acho, não sei e não sei por que (minha página de manual da coluna diz 2004, no ubuntu 18.04, não tenho certeza se o ubuntu obterá uma nova versão) . Enfim, isso funciona para mim e comente se você tiver alguma sugestão.

Peruz
fonte