Realmente es bastante ingenioso. Vamos a descomponerlo. El comando ex
g/^$/xyzzy
buscará todas las líneas vacías y ejecutar el comando xyzzy
(un arbitraria ex
de comandos) en cada uno de ellos.
el truco aquí es que el comando xyzzy
en su caso es otro comando sustituto:
,/./-j
El ,/./-
especifica un rango. Esto tiene el formato <start>,<end>
y, como no hay nada antes de la coma, asume que la línea actual (aquella en la que encontró la línea en blanco) es el inicio.
Después de la coma es /./-
que significa búsqueda del siguiente carácter (.
significa cualquier carácter) luego de vuelta hacia arriba una línea (/./-
es la abreviatura de /./-1
ya que el que se da a entender si no se da ningún valor). Encontrará el patrón .
en la primera línea que no esté en blanco después de la que está operando.
En otras palabras, el final del rango es la última línea en blanco después o en la que está actualmente operando.
Luego ejecuta una unión en ese rango.
Si el inicio y el final del rango eran iguales (solo había una línea en blanco en la sección), unirse no hace nada. Si no son iguales, join los unirá a todos.
Esa es la manera en que combina múltiples líneas en blanco en una sola.
Veamos un ejemplo (los números de línea no se encuentran en el archivo):
1 Line 1
2
3 Line 3
4 Line 4
5
6
7
8
9 Line 9
El comando :g
encontrará todas las líneas en blanco y llevar a cabo su operación en ellos (líneas 2, 5, 6, 7 y 8).
Para la línea 2, ,/./-j
configurará un rango de 2 a 2 (el siguiente .
se encuentra en la línea 3 y luego resta 1). Una combinación en el rango 2,2 no hace nada.
Para la línea 5, ,/./-j
configurará un rango de 5 a 8 (el siguiente .
se encuentra en la línea 9 y luego resta 1). Una unión en el rango 5,8 unirá todas esas líneas juntas.
No soy completamente estoy seguro de esto, pero creo que la operación puede no realizarse en líneas que desaparecen como parte de una operación anterior. Eso es porque no tendría sentido procesar las líneas que se han eliminado anteriormente en el ciclo.
En otras palabras, como las líneas 6 a 8 se eliminan (combinadas con la línea 5), el comando global no funciona en ellas después de eso. Baso eso en nada más que el hecho de que la documentación vim establece un algoritmo de dos pasos, uno para marcar las líneas, y otro para realizar la operación.
I puede equivocarse en ese punto (no sería la primera vez) pero es un detalle de implementación que no afecta la funcionalidad.
Gracias. Esto fue muy clarificador. No sabía que la parte del "comando XYZ" de: g podría especificar un rango. –
El comando XYZ puede ser cualquier comando 'ex', incluido otro sustituto. Me imagino que podrías unir algunos más si quisieras una prueba de _vrazier_ de vim :-) – paxdiablo
¡Eso es increíble! Estaba intentando averiguar cómo unir múltiples comandos ex el otro día ... gracias. – sml