Comprender las diferencias de referencia de línea a través de: g / ^ / norm y a través de:% norm


8

Digamos que tengo el siguiente archivo muy simple

a
b
c
d
e

y he decidido que quiero agregar líneas vacías después de cada línea. Varios métodos diferentes saltan inmediatamente a mi mente. Podríamos hacerlo (y así aceptar el fracaso). Podríamos grabar una macro como qqo<ESC>jqy repetirla varias veces.

Otros dos métodos me parecieron más obvios en ese momento.

En primer lugar, pensé que emitiría el :normcomando oen cada línea. Entonces corro :%norm o. Pero lo que realmente sucede es que obtenemos 5 líneas en blanco, seguidas por las líneas no separadas como se indicó anteriormente. Interpreto que esto significa que %norm, en realidad, vim recoge el mensaje emitiendo el siguiente comando normal en las primeras cinco líneas de este archivo de cinco líneas . El ocomando crea una nueva línea y vim es "tonto" en el sentido de que hace referencia por número de línea y no por algún otro identificador.

Bueno, estaba avergonzado. Por supuesto. Intenté algunas otras cosas para ver si podía hacer que el método anterior funcionara, pero, por desgracia, no pude. Por curiosidad, probé mi otro método de aplicación masiva favorito. Esto me llevó a intentarlo :g/^/norm o. Para mi sorpresa, ¡esto funciona bien! Entonces, a mis ojos, parece que vim no es "tonto" aquí de la misma manera que arriba y hace referencia a las líneas en más que solo el número de línea.

¿Qué está pasando exactamente?


2
En una nota: también puede hacerlo de esta manera: :%s/$/\r/, o como esto: :%s/\n/\r\r/. La conclusión es que las nuevas líneas pueden coincidir \n, pero deben escribirse como \rvalores de reemplazo.
lcd047

Respuestas:


9

Bueno, %es la abreviatura de 1,$(un rango desde la primera línea hasta la última). De :he :%:

Line numbers may be specified with:             :range E14 {address}
        {number}        an absolute line number
        .               the current line                          :.
        $               the last line in the file                 :$
        %               equal to 1,$ (the entire file)            :%

Y para :global:

The global commands work by first scanning through the [range] lines and
marking each line where a match occurs (for a multi-line pattern, only the
start of the match matters).
In a second scan the [cmd] is executed for each marked line with its line
number prepended.  For ":v" and ":g!" the command is executed for each not
marked line.  If a line is deleted its mark disappears.

Entonces, el primer caso es como atravesar una lista mientras se modifica, por lo que un contador en los elementos de la lista se invalida. En el segundo caso, marcamos los elementos a los que queremos apuntar en una pasada, de modo que incluso si la lista se modifica en la segunda pasada, aún sabemos en qué elementos queremos trabajar.


Ah, incluso está en el archivo de ayuda para global. Que tonto soy. Gracias
davidlowryduda

hombre - g es excesivamente loco, útil. Tengo que pasar más tiempo para ir de usuario medio vi para usuario avanzado
javadba
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.