Vim - Ajout d'une ligne vide entre les lignes


15

Comment insérer une ligne vierge entre toutes les lignes non vides?

par exemple. de

line 1
line 2
line 3

line 4
line 5

à

line 1

line 2

line 3

line 4

line 5

Réponses:


27

La commande: g de Vim est conçue pour exactement ce genre de tâche; exécuter une seule action sur chaque ligne qui correspond à un modèle particulier. Voici ma réponse:

:g/.\n\n\@!/norm o

Le motif que j'utilise est /.\n\n\@!/. Décomposant cela en ses composants:

  • .Correspond à n'importe quel caractère de la ligne. (utilisé pour éliminer immédiatement toutes les lignes vides existantes)
  • \n Correspond à un seul \ n à la fin du caractère ci-dessus
  • \n\@! Échoue la correspondance s'il y en a un autre \ n immédiatement après le \ n précédent.

(Vérifiez :h E59pour plus d'informations sur \@!les spécificateurs de correspondance similaires dans les expressions régulières - il y en a quelques autres aussi!)

Ainsi, l'expression régulière de la commande: g a maintenant sélectionné chaque ligne non vide qui se termine par une seule nouvelle ligne et qui n'est pas suivie d'une ligne vide.

Après le modèle dans une :ginstruction vient la commande à exécuter sur les lignes correspondantes. Dans ce cas, je lui ai dit d'exécuter une commande en mode normal (en abrégé norm), et la commande à exécuter est simplement o, ce qui insère une ligne vide sous la ligne actuelle.

Ainsi prise ensemble, la commande trouve chaque ligne qui n'a pas de ligne vide en dessous et en ajoute une. Et c'est tout ce qu'il y a à faire! Vous voudrez peut-être consulter l' article Power of G du wiki vim pour plus de choses fantaisistes avec lesquelles vous pouvez faire :g(et c'est la sœur négative :v) qui ne l'ont pas.


1
Précisément. Je recherche généralement des raccourcis, :%norm omais il s'avère que cela ne fonctionne pas comme prévu dans le cas de o. 1
sehe

Tapez :%s/$/, puis appuyez ^V, puis appuyez sur Enter.
jpaugh

1
@jpaugh En supposant que vous vouliez dire :%s/$/<C-V><CR><CR>(pour utiliser le codage vim-folk commun des touches), cette approche ajoute simplement une nouvelle ligne après chaque ligne. Autrement dit, les lignes qui sont déjà séparées par des blancs (voir Ligne 3 -> Ligne 4, dans le texte d'exemple) finissent par obtenir des lignes vierges supplémentaires. La question d'origine était d'éviter d'ajouter des lignes vierges supplémentaires là où elles existaient déjà dans le texte de départ.
Trevor Powell

3

Lorsque j'ai testé la réponse globale de recherche et de remplacement de @ NeilForester, j'ai constaté qu'il manquait chaque remplacement prévu sur deux lignes consécutives non vides si les lignes n'avaient qu'un seul caractère dans chacune. Cela semble être dû au fait que le motif commence à correspondre à chaque occasion après le dernier caractère correspondant à l'occasion précédente.

L'utilisation de lookbehind et lookahead résout ce problème et raccourcit également l'expression régulière:

:%s/\n\@<!\n\n\@!/\r\r/g

Merci! Cela fonctionne, et il n'ajoute pas plus de lignes si je lance à nouveau la recherche (si disons, j'ai ajouté de nouvelles lignes dans mon fichier).

1
Pourriez-vous expliquer ce que signifie chacune des expressions rationnelles du modèle de recherche? En regardant l'aide de vim, \n\@<!\nsignifie que tout saut de ligne qui n'est pas juste après un autre saut de ligne est-ce correct? Mais je ne pouvais pas comprendre ce que cela \n\@!signifie. J'aimerais le comprendre pour que je puisse l'apprendre et l'appliquer à d'autres modèles de recherche :)

Oui, \n\@<!\nsignifie tout saut de ligne qui ne suit pas immédiatement un autre saut de ligne. \n\@!correspond à une largeur nulle si l'atome précédent (c'est-à-dire \n) ne correspond pas juste avant ce qui suit. Essayez :help \@<!de voir la documentation à ce sujet dans vim. I
Simon

3

Autrement:

%s/\(.\)\n\(.\)/\1\r\r\2/

Ce qui signifie,

\(.\) match and capture a non-newline character,
\n    match a newline
\(.\) match and capture a non-newline character

remplacer par: première capture, double retour à la ligne et deuxième capture.

Par exemple, les line1\nLine2résultats dans \1 = 1et \2 = L.


0

Corrigez-moi si je me trompe. Je crois que vous utilisez la lettre k en mode commande pour descendre d'une ligne. Entrez ensuite en mode insertion et ajoutez la ligne suivante. Répéter au besoin? J'espère que cela t'aides!


kmonte d'une ligne. jdescend d'une ligne.
Neil Forrester

Oui, en effet. Mon erreur. Merci Neil!

0
/[^\n]\n[^\n]
:map <F2> no<esc><F2>

Appuyez ensuite sur <F2>. Cela recherchera deux lignes non vides consécutives, puis ajoutera une ligne entre elles, à plusieurs reprises.

Éditer:

Voici une autre façon de procéder avec une seule recherche globale et un remplacement:

:%s/\([^\n]\)\n\([^\n]\)/\1\r\r\2/g

Mon fichier contient beaucoup de lignes. Existe-t-il un moyen de faire une recherche d'expression régulière et d'insérer une ligne vierge pour l'ensemble du fichier? J'ai regardé stackoverflow.com/questions/2673209/… mais je n'ai pas pu comprendre ce que toutes les commandes regex signifient.

Voir ma modification ci-dessus pour une autre façon d'accomplir la même chose dans une seule commande, et sans mappage récursif. La première façon devrait fonctionner pour tout le fichier.
Neil Forrester

0

Essayez cette commande ( 16caractères):

:%!sed G|cat -s

Au lieu de tenter de "vimgolf" une commande courte, une petite explication des options plutôt obscures utilisées serait plus utile.
Ingo Karkat

0

Je ne sais pas quelle est la longueur de votre fichier, mais l'une des méthodes les plus simples consiste à taper oen mode commande. Et dans la ligne suivante .. Cela pourrait être chargé dans une simple macro.

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.