Vim: coller des lignes ligne par ligne


8

Supposons que j'ai un fichier contenant:

xxx
yyy
zzz

et un autre fichier:

kkk
qqq
ppp

Je souhaite obtenir:

xxxkkk
yyyqqq
zzzppp

Est-ce possible dans Vim avec une commande? (J'ai essayé d'utiliser VISUAL BLOCK mais sans succès).

Dans mon cas particulier, j'ai deux gros fichiers avec de nombreuses lignes à coller, donc la réponse pourrait également être une commande shell, mais je voudrais savoir s'il existe un moyen de le faire même dans le même fichier.

Réponses:


12

Depuis la ligne de commande, vous pouvez essayer

paste -d '\0' file1 file2 > file3

Cela fait exactement ce que vous voulez.

Le mode Visual Block dans vimest également parfaitement adapté à cette tâche. Êtes-vous sûr de l'avoir fait correctement? Vous devriez

  • Passer en mode de blocage visuel
  • Sélectionnez le texte et appuyez sur ypour tirer
  • Accédez à l'autre fichier, dans le coin supérieur gauche du pour coller des données (en dernier x) et appuyez sur p.

Je collais dans Visual Block ... c'est exactement ce que je voulais faire. Je vous remercie.
Fabio F.

1
Au moins avec GNU Coreutils, paste -d '' ...fonctionne également. Fait intéressant, la page de manuel et les pages d'informations de coreutils ne semblent pas documenter «\ 0», même si elles sont spécifiées dans la spécification Unix unique.
derobert

5

Vous pouvez le faire directement lors de l'édition file1. Tapez :pour basculer vers command modedans vim. Tapez ensuite:

%!paste -d '' - file2

3

Voici un moyen de le faire dans le même fichier en utilisant uniquement Vim.

Cela implique un mappage de clés. Je l'ai trouvé une fois lorsque j'ai voulu organiser plusieurs listes en structures de type tableau dans un texte simple.

Cela s'appuie sur la touche } (accolade droite) pour ignorer les limites des paragraphes. (Les accolades sont reflétées, btw: { saute vers le haut du fichier et } vers la fin.)

Donc ... supposons que vous ayez un fichier de données comme celui-ci (cela suppose que les lignes # sont activées avec : set nu ):

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

Il est important que la ligne n ° 4 soit une ligne vide (sans espace), je vais vous expliquer pourquoi dans un instant.

Exécutez la commande map suivante
:: map q mw} jdd'wpkJj

Cela lie la touche "q" à un programme de 12 caractères, que je décrirai en détail ci-dessous.

Lorsque vous appuyez sur "q", il exécute ce programme; notez que votre curseur, qui a commencé sur la ligne # 1, est maintenant sur la ligne suivante, prêt à frapper à nouveau "q". Vous avez peut-être remarqué qu'il y a un espace entre "xxx kkk"; si vous ne le voulez pas, voyez "Qu'en est-il du personnage Extra Space?" ci-dessous, vers la fin.

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

Voici une ventilation de la cartographie:

   :map q mw}jdd'wpkJj
   ^

Les deux points vous mettent en mode commande afin que nous puissions émettre la commande "map".

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

la carte q lie q avec la séquence de caractères suivante. Notez que "q" est juste ma touche "mapper" habituelle; vous pouvez utiliser d'autres touches. Par défaut, q minuscule est mappé pour démarrer l'enregistrement de macro; puisque j'utilise rarement (jamais?) que je trouve "q" plus utile pour les macros utilitaires ponctuelles. Vous pouvez également utiliser des majuscules Q (par exemple, la carte Q) ou une touche fnct, etc.

Maintenant, chaque fois que vous appuyez sur "q" (en mode navigation), vim exécutera cette série de frappes:

   mw}jdd'wpkJj

Ce qui bien sûr ressemble à du charabia total, donc je vais le décomposer action par action (avec les ^^ ci-dessous) pour faciliter le suivi de ce qui se passe.

mw}jdd'wpkJj
^^

Le mw MARQUE un emplacement nommé, le nom ici est «w». J'utilise «w» par défaut (je pense que c'est mon emplacement de «travail». Tout emplacement nommé, à partir de az fonctionnerait, tant que vous êtes cohérent.
Le «w» réapparaîtra un peu lorsque nous voulez ramener le curseur sur cette ligne.

mw}jdd'wpkJj
  ^

Ici, nous avons le bouclé à droite } qui fait sauter le curseur vers la limite de paragraphe suivante; en d'autres termes, cela déplace le curseur sur la ligne vide suivante, qui est la ligne # 4 dans notre exemple. (C'est pourquoi la ligne # 4 devrait être une ligne vide; pas d'espace, sinon } ne la considérera pas comme une frontière.)

mw}jdd'wpkJj
   ^

Le j descend d'une ligne; c'est la navigation old-school vi "hjkl". Vous pouvez également utiliser une flèche vers le bas ici, je trouve "j" un peu plus facile à lire et plus facile à utiliser (car les touches fléchées ne sont pas toujours au même endroit entre les différentes marques de claviers d'ordinateur portable et de bureau, mais "hjkl "est garanti d'être toujours sur le côté droit de la ligne d'accueil de n'importe quel clavier QWERTY (ce qui aide ma vitesse de frappe)).
Quoi qu'il en soit, à ce stade, le curseur est sur la ligne # 5.

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

mw}jdd'wpkJj
    ^^

Le dd est la commande d'édition "supprimer la ligne", il supprime donc la ligne actuelle, qui est la ligne # 5 avec le "kkk" dessus. La suppression de la ligne la place également dans le tampon de collage par défaut, que nous utiliserons pour exploiter pour ramener "kkk" à l'endroit où nous le voulons sur la ligne # 1, à côté de "xxx".

mw}jdd'wpkJj
      ^^

La séquence 'w (guillemet simple w) ramène le curseur à notre signet pour "w", ce qui place le curseur sur la ligne # 1.

mw}jdd'wpkJj
        ^

Le "p" en minuscule place le tampon par défaut actuel (avec "kkk", comme vous vous en souvenez) après le curseur. Puisque le tampon contient ce qui était auparavant la ligne 5, notre fichier ressemble brièvement à ceci maintenant:

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

Notez comment "kkk" est devenu la ligne # 2. (Je ne peux pas facilement illustrer où le curseur va là ... il devrait vraiment être au début de la ligne # 2).
Nous sommes proches mais pas encore tout à fait là ...

mw}jdd'wpkJj
         ^^

Le k en minuscule saute le curseur jusqu'à la ligne # 1 (navigation "hjkl" à nouveau), et le J majuscule joint la ligne suivante sur la ligne actuelle, ce qui donne à notre fichier l'apparence suivante (le curseur est toujours sur la ligne # 1, entre les x et les k):

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


mw}jdd'wpkJj
           ^

Le dernier j est encore une fois la navigation "hjkl", ce qui déplace le curseur vers la ligne n ° 2, ce qui est pratique car c'est la ligne suivante à laquelle nous voulons appliquer q .
Quoi qu'il en soit, cela ressemblera à ceci:

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

Si vous appuyez à nouveau sur "q" et cela ressemblera à ceci (notez que le curseur est sur la ligne # 3).

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

Rincez et répétez si nécessaire. Je trouve cela pratique pour les listes plus longues, car cela me permet de construire (assez) sans douleur des colonnes.

Voici un exemple plus long. L'ajout d'une ligne vierge à la ligne 7 entraîne l'empilement de "ggg" en premier dans la colonne suivante. Après être descendu à "lll", remontez votre curseur jusqu'à la ligne # 1 (gauche bouclé, {, fonctionne bien pour cela) et continuez avec "mmm". Si vous décidez que vous n'aimez pas tout à fait la façon dont cela se déroule, maintenez un peu la touche u (undo) et ajustez où votre ligne "limite" est alors recommencée.

C'est l'une de ces choses qui fonctionne beaucoup plus facilement qu'il ne faut d'effort pour l'expliquer. Bien que je ne pense pas que je l'utiliserais pour joindre des milliers de lignes, je le trouve pratique pour des dizaines et parfois des centaines.

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

Qu'en est-il du personnage Extra Space?
Une partie du comportement de la commande Join est qu'elle met un espace entre les lignes qu'elle joint.
Si vous ne voulez pas d' espace entre "xxx kkk", vous pouvez
ajouter une commande de suppression (x) à la chaîne:

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

Le "join + x" tue l'espace en utilisant le x juste après avoir joint les deux lignes ensemble. x en mode Navigation supprime le caractère sur lequel se trouve le curseur, qui dans ce cas était le caractère d'espace incriminé.

La "jointure avec virgule" remplace l'espace par une virgule. C'est à peu près la même chose, mais nous allons parcourir la dernière partie qui est juste un peu différente de l'exemple précédent.

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

Le R nous place en mode Édition (en particulier le mode Remplacer, qui écrasera tous les caractères avec ce que nous tapons).

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

Le , tape littéralement une virgule, qui remplace l'espace incriminé à ce point.

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

Et puis ^ [ signale un caractère d'échappement, qui quitte le mode édition et nous remet en mode navigation.
Maintenant, nous sommes prêts pour le dernier j pour nous emmener à la ligne suivante.

Pour mapper un caractère d'échappement, vous devez appuyer sur ^ Q (Windows) ou ^ V (Linux et Unix), puis appuyez sur la touche Échap (si vous ne le faites pas, le caractère Échap abandonnera la commande et votre gauche se demandera pourquoi votre carte éventuellement complexe définition vient de disparaître). Voici la séquence que vous devez saisir pour l'intégrer dans Vim sous Windows:

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

Donc. Il existe probablement des dizaines de façons de faire ce genre de chose Vim.
Lorsque les délimiteurs "champ" sont importants, je mets généralement une simple séquence unique à la fin de chaque ligne avec la recherche globale et le remplacement, continuez et joignez les colonnes comme je le souhaite, puis remplacez-tout pour obtenir le séparateur spécifique que je veux .

Quoi qu'il en soit, ce n'est qu'un exemple. J'espère que vous l'avez trouvé intéressant.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.