¿Cómo funciona: g /^$/,/./- j (reducir varias líneas en blanco a un solo espacio en blanco) en vim?

21

En el artículo, Expresiones regulares de Vim , Oleg Raisky da el siguiente comando para reducir varias líneas en blanco a un solo espacio en blanco:

:g/^$/,/./-j

¿Alguien puede describir cómo funciona esto?

:gcomando y expresiones regulares. Pero no entendí lo que hace la parte /,/./-j.

200_success
fuente

Respuestas:

24

Realmente es bastante ingenioso. Vamos a desglosarlo. El excomando

g/^$/xyzzy

buscará todas las líneas vacías y ejecutará el xyzzycomando (un excomando arbitrario ) en cada una de ellas. Tenga en cuenta que xyzzyno es un comando real ex , solo está allí como marcador de posición, según el siguiente párrafo.

La parte difícil aquí es que el xyzzy"comando" en su caso es otro comando de búsqueda:

,/./-j

El ,/./-especifica un rango. Esto es de la forma <start>,<end>y, dado que no hay nada antes de la coma, se supone que la línea actual (la que encontró la línea en blanco) es el comienzo.

Después de que la coma es lo /./-que significa buscar el siguiente carácter ( .significa cualquier carácter), luego haga una copia de seguridad de una línea ( /./-es la abreviatura /./-1ya que está implícita si no se da ningún valor). Encontrará ese patrón .en la primera línea no 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á operando actualmente.

Luego ejecutas una unión sobre ese rango.

Si el inicio y el final del rango fueron iguales (solo había una línea en blanco en la sección), unirse no hace nada. Si no son iguales, unirse los unirá a todos.

Esa es la forma en que combina múltiples líneas en blanco en una.

Veamos un ejemplo (los números de línea son solo para explicación, no están en el archivo real):

1 Line 1
2
3 Line 3
4 Line 4
5
6
7
8
9 Line 9

El g/^$/comando buscará todas las líneas vacías y realizará su operación en ellas (estas son las líneas 2, 5, 6, 7 y 8).

Para la línea 2, ,/./-jconfigurará un rango de 2 a 2 (el siguiente .se encuentra en la línea 3 y luego resta 1 para obtener 2). Una unión en el rango 2,2 no hace nada.

Para la línea 5, ,/./-jconfigurará 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.

La operación no se realiza en líneas que desaparecen como parte de una operación anterior. Esto se debe a que no tendría sentido procesar líneas que se han eliminado anteriormente en el ciclo.

En otras palabras, debido a que 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.

Eso se basa en el hecho de que la vimdocumentación establece un algoritmo de dos pasos, uno para marcar las líneas y otro para realizar la operación.


fuente
2
Tenga en cuenta que este comando se quejará si tiene líneas vacías al final de su archivo.
Comodín