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 premier passage il marque les lignes contenant le motif
;
- lors de la deuxième passe il opère sur les lignes marquées
Lors du deuxième passage, :g
rejoint la ligne 1;
avec la ligne 2;
car a 1;
été marqué lors du premier passage. Cependant je soupçonne (pas sûr) qu'il ne se joint pas 1; 2;
à 3;
parce que la ligne 2;
n'existe plus, son contenu a été fusionné avec la ligne 1;
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 joindre 3; 4;
à 5;
parce que la ligne 4;
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:
function! JoinLines()
if getline(line('.')-1) =~ ';'
.-1join
endif
endfunction
Utilisez ensuite la commande globale suivante:
:g/;/call JoinLines()
Ou sans fonction:
:g/;/if getline(line('.')-1) =~ ';' | -j | endif
Solution 2 (sans vimscript)
:g/;/.,/^[^;]*$/-1j
Chaque fois que la commande globale :g
trouve le modèle, ;
elle exécute la commande: .,/^[^;]*$/-1j
Il peut être décomposé comme ceci:
:g/pattern/a,bj
Où :
pattern = ;
a = . = number of current line
b = /^[^;]*$/-1 = number of next line without any semicolon minus one
b
peut être décomposé comme ceci:
/ = look for the number of the next line matching the following pattern
^ = a beginning of line
[^;] = then any character except a semicolon
* = the last character can be repeated 0 or more times
$ = an end of line
/ = end of pattern
-1 = removes one to the number you just got
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
et b
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 entre a
et b
, 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:
:help :global
:help :join
:help :range
: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.