Je voudrais joindre des lignes ensemble uniquement pour les lignes qui ont un certain modèle (comme ;
), mais lors de l'utilisation, g/;/j
cela ne fonctionne pas comme prévu, sauf si appelé deux fois.
Par exemple le contenu suivant:
a
1;
2;
3;
4;
5;
b
6;
7;
8;
9;
c
lors de l'utilisation: :g/;/j
la sortie est:
a
1; 2;
3; 4;
5; b
6; 7;
8; 9;
c
ou :g/;/-j
donne:
a 1; 2; 3; 4; 5;
b 6; 7; 8; 9;
c
similaire avec: :g/;\_.\{-};/j
.
Ma sortie attendue est:
a
1; 2; 3; 4; 5;
b
6; 7; 8; 9;
c
ou quelque chose de similaire, donc toutes les lignes contenant le motif sont jointes.
Comment cela peut-il être réalisé?
global-command
Kenorb
la source
la source
:g/;/j
ne fonctionne pas car il se fait en deux passes: d'abord le tampon est analysé, puis la commande est appliquée aux lignes correspondantes.Réponses:
Explication possible du problème
Je pense que la raison pour laquelle cela
:g/;/j
ne fonctionne pas est que la:g
commande fonctionne avec un algorithme à 2 passes:;
Lors du deuxième passage,
:g
rejoint la ligne1;
avec la ligne2;
car a1;
été marqué lors du premier passage. Cependant je soupçonne (pas sûr) qu'il ne se joint pas1; 2;
à3;
parce que la ligne2;
n'existe plus, son contenu a été fusionné avec la ligne1;
qui a déjà été traitée.:g
Recherche donc la ligne suivante qui a été marquée lors du premier passage (3;
) et la joint à la suivante (4;
). Après que les répétitions de problème, il ne peut pas se joindre3; 4;
à5;
parce que la ligne4;
n'existe plus.Solution 1 (avec vimscript)
Vous pourriez peut-être appeler une fonction chaque fois qu'une ligne contenant
;
est trouvée pour vérifier si la ligne précédente contient également un point-virgule:Utilisez ensuite la commande globale suivante:
Ou sans fonction:
Solution 2 (sans vimscript)
Chaque fois que la commande globale
:g
trouve le modèle,;
elle exécute la commande:.,/^[^;]*$/-1j
Il peut être décomposé comme ceci:
Où :
b
peut être décomposé comme ceci:j
est la forme abrégée de la commande Ex:join
qui, comme la plupart des autres commandes Ex, peut être précédée d'une plage.Ici, elle est précédée de la plage:
.,/^[^;]*$/-1
(a,b
)Une plage suit la forme
a,b
oùa
etb
sont généralement 2 numéros de ligne, et vous permet d'opérer sur un groupe de lignes dont le nombre est compris entrea
etb
, au lieu d'une seule.La
j
commande joint donc toutes les lignes entre la ligne courante (a
) et la suivante qui ne contient pas de point-virgule moins une (b
).Pour plus d'informations, voir:
la source
Je fais de même en me joignant tout le temps avec une recherche globale et je remplace:
\n
correspond à la nouvelle ligne.Pour rechercher et supprimer des lignes vides:
Je ne sais pas pourquoi, mais si vous voulez insérer une nouvelle ligne, vous devez utiliser
\r
la source
s
seul ne fonctionnera que pour une seule ligne, pour le rendre global, vous devez l'utiliser%s
, mais il rejoindra presque toutes les lignes, y compris les non;
lignes:s
commande exactement pour ce que vous voulez. Je pense que cela%s/;\n\(.*;\)\@=/;/
fait ce dont vous avez besoin.