Tout d'abord, étant donné que c'est mon premier message ici, je voudrais juste dire que j'ai trouvé que VIM est un excellent outil et que le forum ici est très utile pour trouver des réponses aux questions, avec beaucoup de gens utiles qui fournissent une aide inestimable. Je suis encore très nouveau sur VIM, donc à peu près tout ce que j'ai appris à ce sujet est venu d'ici.
Ma question est: je sais comment inverser TOUTES les lignes d'un fichier (: g / ^ / m0 entre autres), mais existe-t-il un moyen d'inverser toutes les 4 lignes d'un fichier, de sorte que
line1
line2
line3
line4
line5
line6
line7
line8
...
devient
line4
line3
line2
line1
line8
line7
line6
line5
...
Vous pouvez supposer qu'il y aura toujours un multiple exact de 4 lignes dans ces fichiers.
Réponses:
La commande
:Reverse
expliquée sur Vim Wiki peut être utilisée pour cela (vous pouvez l'inclure dans votre.vimrc
pour la rendre permanente):Ensuite, vous pouvez enregistrer une macro pour exécuter la commande sur toutes les quatre lignes:
Explication:
qm
: 'q' en mode normal démarre (et arrête) l'enregistrement d'une macro dans un registre donné (registre 'm', dans ce cas, mais il peut s'agir de n'importe quelle autre lettre)V
: passer en mode visuel et sélectionner la ligne courante3j
: étendre la sélection visuelle aux 3 lignes suivantes:Reverse<cr>
: exécutez la commande Inverser sur les lignes sélectionnées (<cr>
ici représente la enterclé)4j
: passer aux lignes suivantes inchangéesq
: arrête l'enregistrement de la macro1000@m
: exécutez la macro enregistrée au registre 'm' 1000 fois (vous pouvez augmenter ce nombre si votre fichier est supérieur à 4000 lignes)Éditer:
Comme mentionné dans les commentaires, vous pouvez utiliser une macro récursive au lieu d'utiliser un nombre:
qM
: si le registre spécifié pourq
est en majuscule, la macro est ajoutée au registre (ce qui est également utile lorsque vous réalisez que vous avez manqué les dernières étapes d'une macro complexe)@m
: exécuter la macro sur le registrem
q
: arrêtez d'ajouter la macroBien qu'il soit créé en tant que macro, vous pouvez créer une commande pour cela s'il s'agit d'une tâche courante sur votre flux de travail:
function! Reverse4()
/endfunction
: définit une nouvelle fonctionlet reg_m = @m
: enregistre le contenu actuel du registrem
let @m = "<c-r><c-r>m"
: insérez la macro dans le registrem
- notez que<c-r>
c'est la notation vim pour Ctrl+ ret que vous devez taper ceci, pas copier / coller, donc votre ligne sera similaire àlet @m = 'V3j:Reverse^M4j@m'
et elle contiendra un caractère spécial (^ M)normal! @m
: la commande normale exécute son argument tel qu'il a été tapé en mode normal, il exécutera donc la macro récursivelet @m = reg_m
: restaure le contenu du registrem
, vous n'avez donc pas à vous souvenir que ce registre est utilisé sur cette fonction et évitez de l'utilisercommand! Reverse4 call Reverse4()
: créer une nouvelle commande pour cette fonctionSelon vos besoins, vous pouvez l'améliorer, par exemple: passer un argument à la commande et à la fonction pour que cela fonctionne pour n'importe quel nombre de lignes au lieu d'être fixé par groupe de 4 lignes.
la source
1000@q
hack, vous pouvez également utiliser une macro récursive:qmqqm ... @mq@m
.command! -bar -range=% Reverse <line1>,<line2>g/^/m<line1>-1|nohl
quelque part dans votre vimrc.Comme pour toutes les actions répétitives , si vous pouvez faire quelque chose une fois avec des opérations d'édition de base, vous pouvez facilement le faire plusieurs fois en enregistrant une macro.
(Dans ce cas, je vais utiliser une macro récursive, mais vous pouvez simplement enregistrer une macro non récursive et la lire plusieurs fois en martelant
@@
ou en utilisant un compte.)En panne
gg
: Passer au début du fichier.qqq
: Effacer le registreq
. Nous verrons pourquoi cela est nécessaire à l'étape 5.qq
: Démarrer l'enregistrement d'une macro pour s'enregistrer qddjjpkddkkPjddpjj
: Une série d'opérations qui réorganise les quatre premières lignes simplement en les supprimant et en les collant manuellement. (Cela peut sembler compliqué à première vue, mais ne soyez pas trompé c'est quelque chose de très basique que vous auriez appris dans les 5 premières minutes environ de.vimtutor
:j
,k
,dd
,p
,P
)@q
: Appelez la macro! À ce stade, le registreq
ne contient rien (car nous l'avons effacé à l'étape 2), donc rien ne se passera.q
: Arrêtez l'enregistrement de la macro.@q
: Relisez la macro récursive autant de fois que nécessaire.NB Ce qui précède ne produira pas les résultats souhaités si le fichier contient un nombre de lignes qui n'est pas exactement divisible par quatre. Afin d'arrêter la macro tôt s'il ne reste pas quatre lignes, nous devons exécuter une commande en mode normal Vim qui échouera, avant de commencer à appliquer les modifications à l'étape 4. Nous pouvons le faire en essayant de descendre une ligne trois fois (puis sauvegarder) avant de commencer à déplacer les lignes:
jjj3k
Donc:
la source
q
, il doit être vide, sinon il gâchera vos éditions.qqqggqqjjjkddkkPjddjpkddkkPjjjj@qq@q
where I can just use the one-line custom command each time I need to do this
- notez que vous n'avez pas à recréer la macro chaque fois que vous en avez besoin, car il est possible de la stocker en tant que fonction / commande sur votre vimrc.Vous pouvez également le faire avec une
Ex
commande utilisantsed
comme filtre externe:Cette version ignorera (supprimera) toutes les lignes supplémentaires au-delà d'un multiple de 4. Pour conserver le dernier ensemble de moins de 4 lignes (inversé), utilisez:
Le
%
moyen ici « Chaque ligne du tampon. »La
!
commande signifie «Exécutez la commande suivante avec les lignes spécifiées en entrée et remplacez les lignes spécifiées par la sortie de la commande». (Cela s'appelle un filtre; très pratique pour des choses comme le tri, par exemple,:%!sort
triera toutes les lignes de votre fichier;:2,8!sort
triera les lignes 2 à 8, etc.)sed
est l' outil d' édition de flux et se trouve sur tous les systèmes de type Unix. Les concepts cléssed
utilisés ici sont l '"espace modèle" (qui, par défaut, contient uniquement chaque ligne de l'entrée à son tour), et l' "espace d'attente" (qui est l'endroit où vous pouvez coller du texte supplémentaire lors de l'utilisationsed
pour l'enregistrer lors du traitement d'autres lignes d'entrée).-n
est une option de lased
commande pour supprimer ses actions par défaut d'impression de l'espace de motif (car dans ce cas, nous ne voulons imprimer que lorsque nous le disons explicitement.)$p
dans lased
commande signifie "Si vous êtes sur la dernière ligne desed
saisie, imprimez (l'espace de motif)."h
signifie "coller le contenu actuel de l '" espace modèle "dans" l'espace d'attente ", en écrasant tout ce qui s'y trouve."n
signifie "remplacer le contenu de" l'espace modèle "par la ligne suivante de l'entrée."G
signifie "ajouter à l '" espace modèle ": une nouvelle ligne suivie du contenu de" l'espace d'attente "."Dans l'ensemble, la
sed
commande stocke quatre lignes de sortie, les inversant telles qu'elles les stockent, puis les imprime. Les$p
commandes ajoutées dans la deuxième version garantissent que si la dernière ligne du fichier est atteinte autrement que sur un multiple de 4 lignes, les lignes sont toujours imprimées.Pour une approche alternative et interactive sans utiliser de fonctionnalités spécifiques à Vim et sans utiliser de filtre externe:
pour aller à la quatrième ligne.
pour inverser les quatre lignes précédentes (1-4) et laissez votre curseur sur la ligne 8.
.m -4
déplace la ligne actuelle juste après la ligne de quatre lignes en arrière (en laissant le curseur sur la ligne déplacée).+3m .
déplace la ligne qui se trouve 3 lignes après la ligne actuelle, juste après la ligne actuelle, en laissant le curseur sur la ligne déplacée.+2m .
bien sûr fonctionne de la même façon.+5
place le curseur à cinq lignes de l'endroit où il se trouve.Répétez comme vous le souhaitez.
Dans Vim, vous pouvez répéter toute cette commande avec
@:
, puis recommencer avec@@
. En Posixvi
ouex
vous devez insérer:.m -4 | +3m . | +2m . | +5
une ligne de texte, supprimer un tampon appelé (registre), puis exécuter ce tampon appelé (registre).Donc en
ex
mode, inverser les lignes de manière interactive en utilisant uniquement les fonctionnalités spécifiées par POSIX, et en commençant par 17 lignes de texte:Lectures complémentaires:
ex
vi
la source
4G:.m -4 | +3m . | +2m . | +5<Enter>@:
puis@@
répétée jusqu'à ce que votre fichier soit entièrement traité. Je recommande cependant d'installer MobaXterm. :)Anglais simple: pour chaque ligne, déplacez la ligne actuelle vers le haut
lnum % 4
, sauflnum % 4 == 0
dans ce cas, déplacez la ligne actuelle vers le haut4
.De plus, pour inverser toutes les
n
lignes, remplacez le4
'dans la commande ci-dessus parn
.la source