Me gustaría unir líneas solo para líneas que tienen cierto patrón (como ;), sin embargo, cuando g/;/jse usa no funciona como se espera a menos que se llame un par de veces.
Por ejemplo el siguiente contenido:
a
1;
2;
3;
4;
5;
b
6;
7;
8;
9;
c
cuando se usa: :g/;/jla salida es:
a
1; 2;
3; 4;
5; b
6; 7;
8; 9;
c
o :g/;/-jda:
a 1; 2; 3; 4; 5;
b 6; 7; 8; 9;
c
similar con: :g/;\_.\{-};/j.
Mi salida esperada es:
a
1; 2; 3; 4; 5;
b
6; 7; 8; 9;
c
o algo similar, por lo que todas las líneas que contienen el patrón se unen.
¿Cómo se puede lograr esto?
global-command
kenorb
fuente
fuente

:g/;/jno funciona porque se realiza en dos pasadas: primero se escanea el búfer, luego se aplica el comando a las líneas coincidentes.Respuestas:
Posible explicación del problema.
Creo que la razón por la
:g/;/jque no funciona es porque el:gcomando funciona con un algoritmo de 2 pasos:;Durante la segunda pasada,
:gune la línea1;con la línea2;porque1;se marcó durante la primera pasada. Sin embargo, sospecho (no estoy seguro) que no se une1; 2;con3;ya que la línea2;ya no existe, su contenido se ha fusionado con la línea1;que ya ha sido procesado.Entonces
:gbusca la siguiente línea que se marcó durante el primer pase (3;) y la une con la siguiente (4;). Después de eso se repite el problema, no pueden unirse3; 4;con5;porque la línea4;no existe más.Solución 1 (con vimscript)
Tal vez podría llamar a una función siempre que
;se encuentre una línea que contenga para verificar si la línea anterior también contiene un punto y coma:Luego use el siguiente comando global:
O sin una función:
Solución 2 (sin vimscript)
Cada vez que el comando global
:gencuentra el patrón;, ejecuta el comando:.,/^[^;]*$/-1jSe puede desglosar así:
Dónde :
bpuede desglosarse más de esta manera:jes la forma abreviada del comando Ex:joinque, como la mayoría de los otros comandos Ex, puede ir precedida de un rango.Aquí está precedido por el rango:
.,/^[^;]*$/-1(a,b)Un rango sigue la forma
a,bdondeaybgeneralmente son números de 2 líneas, y le permite operar en un grupo de líneas cuyo número está entreayb, en lugar de solo uno.Entonces, el
jcomando une todas las líneas entre la actual (a) y la siguiente que no contiene punto y coma menos uno (b).Para más información, ver:
fuente
Hago uniones similares todo el tiempo con una búsqueda global y reemplazo:
\ncoincide con nueva línea.Para buscar y eliminar líneas en blanco:
No estoy seguro de por qué, pero si desea insertar una nueva línea, debe usar
\rfuente
ssolo funcionará para una línea, para que sea global, debe usarla%s, pero luego unirá casi todas las líneas, incluidas las que no son;líneas:scomando exactamente para lo que quieras. Creo que esto%s/;\n\(.*;\)\@=/;/hace lo que necesitas.