web-dev-qa-db-fra.com

reformater dans vim pour une mise en page de colonne Nice

J'ai cet ensemble de données dans un fichier 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

Comme vous pouvez le voir, les nombres sont formatés différemment et mal alignés. Existe-t-il un moyen dans vim d'aligner correctement les colonnes rapidement, de sorte que le résultat est le suivant

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

Ce serait formidable de copier et coller des sections avec ctrl-v. Des indices?

117
Stefano Borini

Si vous utilisez une sorte d'UNIX (Linux, etc.), vous pouvez le tricher et le filtrer via la commande column (1).

:%!column -t

Ce qui précède analysera les délimiteurs à l'intérieur des littéraux de chaîne, ce qui est incorrect, vous aurez donc probablement besoin d'étapes de prétraitement et de spécifier le délimiteur pour ce fichier, par exemple:

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

Parfois, nous voulons aligner seulement deux colonnes. Dans ce cas, nous n'avons pas besoin de plugins et pouvons utiliser la fonctionnalité Vim pure comme celle-ci:

  1. Choisissez un séparateur. Dans le message d'OP, c'est une virgule, dans mon exemple, c'est =.
  2. Ajoutez des espaces avant/après. J'utilise s/=/= ...spaces... / en sélection visuelle pour cela.
  3. Recherchez le mot le plus long et placez le curseur après.
  4. Supprimez tous les espaces supplémentaires en utilisant dw et le mouvement vertical.

Exemple de cette technique démontrée ci-dessous:

Example

Je n'ai pas besoin d'aligner les choses assez souvent pour installer un autre plugin, donc c'était ma façon préférée de l'accomplir - surtout que cela ne nécessite pas beaucoup de réflexion.

50
rr-

Comme l'a suggéré sunny256, la commande column est un excellent moyen de le faire sur les machines Unix/Linux, mais si vous voulez le faire en pur Vim (afin qu'il puisse également être utilisé dans Windows), le plus simple consiste à installer le plugin Align puis à faire:

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

La première ligne aligne les entrées sur les virgules et la seconde déplace la virgule de sorte qu'elle affleure avec la valeur précédente. Vous pourrez peut-être utiliser AlignCtrl pour définir un mappage personnalisé qui fait tout en une seule fois, mais je ne me souviens jamais comment l'utiliser ...

Modifier

Si cela ne vous dérange pas deux espaces entre les entrées et que vous souhaitez le faire dans une seule commande, vous pouvez également faire:

:%Align ,\zs
24
DrAl
6
slf

C'est une excellente réponse en utilisant des macros vim: https://stackoverflow.com/a/8363786/59384 - en gros, vous commencez à enregistrer une macro, formatez la première colonne, arrêtez l'enregistrement puis répétez la macro pour toutes les lignes restantes.

Copier/coller de cette réponse:

qa0f:w100i <Esc>19|dwjq4@a

Notez l'espace unique après le 100i, et <Esc> signifie "appuyez sur Échap" - ne tapez pas "<Esc>" littéralement.

Traduction:

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

Nous avons maintenant également le fabuleux plugin EasyAlign , écrit par junegunn.

GIF de démonstration de son fichier README:

4
rr-

Vous pouvez utiliser le plugin csv.vim .

:%ArrangeColumn

Cependant, cela ne fera pas exactement ce que vous avez demandé: cela ajustera à droite le contenu des cellules, tandis que vos valeurs seront alignées par le point décimal ou par le premier chiffre.

Le plugin possède de nombreuses autres commandes utiles pour travailler avec des fichiers CSV.

3
Daan

aussi, si vous avez de très longues colonnes, il peut être utile de désactiver l'habillage par défaut

: définir nowrap 
:%! colonne -t 

(notez que dans debian, vous avez également une autre option pour la colonne -n ​​qui, si vous voulez diviser plusieurs délimiteurs adjacents)

2
Amos Folarin

Assez vieille question, mais je me suis récemment prévalu d'un excellent plugin vim qui permet le formatage des tableaux à la volée ou après coup (comme l'exige votre cas d'utilisation):

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

1
Alice

Je viens d'écrire tablign à cet effet. Installer avec

[Sudo -H] pip3 install tablign

Ensuite, marquez simplement le tableau dans vim et faites

:'<,'>:!tablign

enter image description here

1
Nico Schlömer

J'ai écrit le script python qui permet aux utilisateurs de columaliser de manière basique tout type de texte également en dehors de vim. Je ne sais pas si cela fonctionnera pour les utilisateurs Windows ou Mac.

columnice.py Gist

Utilisation en vim.

:'<,'>!columnice =

Cela utilisera le signe égal comme délimiteur. Le délimètre n'est cependant pas jeté.

0
Bassim Huis

Voici une pure réponse de script Vim, pas de plugins, pas de macros:

Il serait peut-être plus clair de commencer avec la solution de mon problème comme exemple. J'ai sélectionné les lignes de code que je voulais affecter, puis j'ai utilisé la commande suivante (rappelez-vous que le fait de passer en mode commande à partir du mode visuel ajoute automatiquement le "'<,'>", afin qu'il agisse sur la plage visuelle):

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

Sauf que je n'ai PAS réellement tapé "<0d>". Vous pouvez entrer des caractères non imprimables sur la ligne de commande en appuyant sur ctrl-v, puis sur la touche que vous souhaitez taper. "<0d>" est ce qui est rendu sur la ligne de commande après avoir tapé ‘ctrl-v enter’. Ici, il est analysé par la commande "normal" comme la sortie du mode de recherche "/". Le curseur passe ensuite à "valeur" sur la ligne actuelle.

Ensuite, nous [D] supprimons simplement le reste de la ligne, passons à la colonne 70 (ou ce dont vous avez besoin dans votre cas), et [P] ut ce que nous venons de supprimer. Cela signifie que nous devons déterminer la largeur de la ligne la plus large, jusqu'à notre recherche. Si vous n'avez pas mis ces informations dans votre ligne d'état, vous pouvez voir la colonne du curseur en entrant la commande en mode normal "g ctrl-g". Notez également que le passage à une colonne qui n'existe pas nécessite le paramètre "virtualedit"!

J'ai laissé le terme de recherche pour la commande: g (lobal) vide, car nous avons utilisé un bloc visuel et nous voulions affecter chaque ligne, mais vous pouvez laisser de côté en utilisant une sélection visuelle (et le "'<,'>") et mettre un terme de recherche là-bas à la place. Ou combinez une sélection visuelle et un terme de recherche pour affiner les choses plus finement/facilement.

Voici quelque chose que j'ai appris récemment: si vous vous trompez sur une commande de mode de commande complexe, annulez avec 'u' (si cela a affecté le tampon), puis appuyez sur "q:" pour entrer un tampon d'historique de commande spécial qui agit un peu comme un tampon conventionnel . Modifiez une ligne et appuyez sur Entrée, et la commande modifiée est entrée en tant que nouvelle commande. Indispensable si vous ne voulez pas avoir à vous soucier de tout formuler parfaitement la première fois.

0
atimholt