Comment inverser l'ordre des lignes pour que la première ligne apparaisse à la fin et la dernière ligne apparaisse en premier? (Il peut s'agir de toutes les lignes d'un tampon, d'une plage d'adresses ou d'une sélection de mode visuel en ligne.)
Je voudrais transformer
rat
ox
tiger
⋮
dog
pig
dans
pig
dog
⋮
tiger
ox
rat
sans recourir à une commande externe telle que tac
.
rearrangement
200_success
la source
la source
Réponses:
Le pouvoir du mondial fonctionnera ici:
Ou, plus simplement (merci @tommcdo)
Le premier correspondra à chaque ligne et pour chaque ligne, supprimez-le et collez-le en haut du fichier. En se déplaçant dans le fichier, il inverse le texte.
La seconde correspond de manière similaire à chaque ligne et la déplace vers le haut du fichier.
Remarque: les deux fonctionnent sur l' ensemble du fichier et ne s'appliqueront pas correctement à l'inversion d'un sous-ensemble de lignes. Voir la réponse d'Ingo Karkat pour une solution qui fonctionne dans une plage.
La description:
g
commande globale/^/
correspond à n'importe quelle ligne qui a un début (c'est-à-dire toutes les lignes)exe
exécute la chaîne suivante"normal
exécute les commandes en mode normaldd
supprime la lignegg
déplace vers le haut du fichierP
colle au-dessus de la position actuellemove 0
déplace la ligne actuelle en dessous de la ligne 0 (ce qui la place à la position 1 ou à la première ligne du fichier)la source
:normal
commande, nous pouvons utiliser la commande Ex:move 0
, qui déplace la ligne au début du tampon.:execute
nécessaire uniquement lorsque la commande doit être construite dynamiquement, par exemple:execute 'normal' g:user_command
.:execute
car je finis souvent par ajouter d'autres commandes Ex après celle existante plus tard, et il est plus pratique pour moi d'y avoir:exe
déjà que d'avoir à revenir en arrière et à l'insérer plus tard. Malheureusement, cette habitude s'est infiltrée dans cette réponse où elle ne s'applique pas autant.:execute
: comme il prend une chaîne, il fournit une délimitation claire de l'endroit où se terminent les commandes en mode normal, même si je ne construis pas la chaîne, il est plus facile pour moi de trouver des guillemets équilibrés que de chercher<esc>
ou quoi que ce soit pour terminer le mode. Encore une fois, c'est une préférence et une habitude personnelles. :-):9,11g/^/move 8
... Le dernier nombre doit être le début de la plage moins 1 (adapté de la réponse d'Ingo).Ce one-liner (pour votre
~/.vimrc
) définit une:Reverse
commande; vous pouvez également utiliser la:global
partie directement, mais la syntaxe de la:move
(qui déplace itérativement les lignes avant le début de la plage, l'inversant ainsi) n'est pas facile à mémoriser:la source
<line1>
&<line2>
est nécessaire pour que cela fonctionne sur une plage, c'est-à-dire::7,9Reverse
(ce sont des fonctionnalités decommand
, pasglobal
oumove
). Le plus simple:command! -bar -range=% Reverse :global/^/m 0
fonctionnera également, mais uniquement pour la totalité du tampon ...Pure Vim:
Explication:
Source: inversez toutes les lignes et la puissance de g sur wikia vim.
Quelques exemples d'utilisation de commandes externes:
tac
(partie de GNU coreutils -cat
inversée):tail
sous BSD / OSX (non compatible POSIX):Pour plus d'idées, voir:
la source
:g/^/m0
la même chose que:g/^/move 0
la réponse de John?tac
). Mais je soupçonne que le downvote était dû à la répétition de la réponse.tac
été mentionné par OP, mais toutes les autres questions similaires seraient en double de toute façon, il est donc bon de le mentionner à nouveau. John a pris cette cmd du commentaire @tommcdo, je l'ai d'abord pris de DerMike , mais je pense qu'il l'a simplement pris de wikia, j'ai donc donné des crédits à vim wikia, donc ce n'est pas complètement en double car l'explication est complètement différente.Dans l'esprit du VimL fonctionnel:
getline(1, line('$'))
renvoie une liste de toutes les lignes du tampon.'$'
est un argument spécial pourline()
lequel indique la dernière ligne du tampon.reverse(...)
inverse la liste d'entrée, sur place. Il faudrait utiliserreverse(copy(...))
si la liste d'entrée ne devait pas être modifiée.setline(1, ...)
remplace la ligne spécifiée par le deuxième argument. Lorsque le deuxième argument est une liste, le même nombre de lignes que la longueur de la liste est remplacé par le contenu de la liste.Si vous le souhaitez, vous pouvez également définir une commande qui prend une plage (
%
tampon entier par défaut )la source
hlsearch
est activé) comme la:g/
commande des autres réponses ... Les performances sont peut-être pires, cependant? Puisqu'ilgetline(1, line('$'))
obtient le tampon entier en mémoire.reverse()
semble être en place, donc cela devrait prendre très peu de mémoire en tant que tel ...Selon la documentation Vim usr_12.txt - Astuces astucieuses
la source
Utilisation de nombres relatifs. Le paragraphe commence à la ligne 13 et spams plus de 4 lignes
la source