Comment fonctionne: g /^$/,/./- j (réduire plusieurs lignes vides en un seul blanc) dans vim?

21

Dans l'article, Vim Regular Expressions , Oleg Raisky donne la commande suivante pour réduire plusieurs lignes vides en un seul blanc:

:g/^$/,/./-j

Quelqu'un peut-il décrire comment cela fonctionne?

Je connais la :gcommande et les expressions régulières. Mais je n'ai pas compris ce que fait la pièce /,/./-j.

200_success
la source

Réponses:

24

C'est vraiment assez ingénieux. Décomposons-le. La excommande

g/^$/xyzzy

recherchera toutes les lignes vides et exécutera la xyzzycommande (une excommande arbitraire ) sur chacune d'elles. Notez que ce xyzzyn'est pas une vraie ex commande, c'est seulement là en tant qu'espace réservé, selon le paragraphe suivant.

L'astuce ici est que la xyzzy"commande" dans votre cas est encore une autre commande de recherche:

,/./-j

Le ,/./-spécifie une plage. Il s'agit du formulaire <start>,<end>et, comme il n'y a rien avant la virgule, il suppose que la ligne actuelle (celle où vous avez trouvé la ligne vierge) est le début.

Après la virgule est /./-ce qui signifie rechercher le caractère suivant ( .signifie n'importe quel caractère) puis sauvegarder une ligne ( /./-est abrégé /./-1car celui-ci est implicite si aucune valeur n'est donnée). Vous trouverez ce modèle .sur la première ligne non vide suivant celle sur laquelle vous opérez.

En d'autres termes, la fin de la plage est la dernière ligne vierge après ou sur celle sur laquelle vous travaillez actuellement.

Ensuite, vous exécutez une jointure sur cette plage.

Si le début et la fin de la plage étaient égaux (une seule ligne vierge se trouvait dans la section), join ne fait rien. S'ils ne sont pas égaux, rejoindre les rejoindra tous.

C'est ainsi qu'il combine plusieurs lignes vides en une seule.

Regardons un exemple (les numéros de ligne sont pour explication seulement, ils ne sont pas dans le fichier réel):

1 Line 1
2
3 Line 3
4 Line 4
5
6
7
8
9 Line 9

La g/^$/commande trouvera toutes les lignes vides et effectuera son opération sur elles (ce sont les lignes 2, 5, 6, 7 et 8).

Pour la ligne 2, ,/./-jétablira une plage de 2 à 2 (la suivante .se trouve sur la ligne 3, puis soustrayez 1 pour obtenir 2). Une jointure sur la plage 2,2 ne fait rien.

Pour la ligne 5, ,/./-jétablira une plage de 5 à 8 (à côté .de la ligne 9 puis soustrayez 1). Une jointure sur la plage 5,8 reliera toutes ces lignes ensemble.

L'opération n'est pas effectuée sur les lignes qui disparaissent dans le cadre d'une opération antérieure. En effet, cela n'aurait aucun sens de traiter les lignes qui ont été supprimées plus tôt dans le cycle.

En d'autres termes, étant donné que les lignes 6 à 8 sont supprimées (combinées avec la ligne 5), la commande globale ne les opère pas après cela.

Cela est basé sur le fait que la vimdocumentation indique un algorithme à deux passes, un pour marquer les lignes, un pour effectuer l'opération.


la source
2
Notez que cette commande se plaindra si vous avez des lignes vides à la fin de votre fichier.
Wildcard