2012-03-28 17 views
34

¿Hay alguna manera de generar una secuencia numérica en vi (m)?vi - ¿cómo generar una secuencia numérica?

Por ejemplo, desde una fila al azar en un archivo (abierto en vim), diga Fila-i - a una fila al azar, diga Row-j, donde Row-i < Fila-j, hay una manera de generar secuencia numérica de la Fila-i a la Fila-j comenzando con el número 1 al número j-i + 1 con el incremento del paso como 1?

Supongo que tengo las siguientes líneas en un archivo.

this is line #1 
this is line #2 
this is line #3 
this is line #4 
this is line #5 
this is line #6 
this is line #7 
this is line #8 
this is line #9 
this is line #10 

Quiero prefijar el número de secuencia de la línea # 4 a la línea # 8 comenzando con el número 1 a número 5. Después de la operación, el archivo resultante debe ser como sigue:

this is line #1 
this is line #2 
this is line #3 
1 this is line #4 
2 this is line #5 
3 this is line #6 
4 this is line #7 
5 this is line #8 
this is line #9 
this is line #10 

Si esto es posible, ¿hay alguna manera de aumentar el recuento de pasos? .for ejemplo, la secuencia debe ser 2, 4, 6, 8, 10 .. es decir con el recuento de paso 2.

Tenga en cuenta:

Este SO post es similar pero no la misma.

+0

Este plugin no es una solución completa para su problema, pero es tremendamente útil para añadir columnas de números: [VisIncr] (http: // vim .sourceforge.net/scripts/script.php? script_id = 670). Documentos [aquí] (http://www.drchip.org/astronaut/vim/doc/visincr.txt.html). FWIW. – lcd047

Respuesta

36

seleccionar varias líneas con V (Shift-v), a continuación, escriba comando abajo:

:let i=1 | '<,'>g/^/ s//\=i . " "/ | let i+=2 

Escriba :help sub-replace-expression para leer más.

+2

¡Gracias por esto! vim es tan poderoso !! Pruebe esto: ': let i = 1 | dejar que j = 1 | '<,'> g/^/s // \ = i/| dejar c = i + j | dejar que j = i | let i = c ' – while

+1

¿Alguien puede explicar esto? – Jin

+0

@Jin Verifique esta publicación para ver el http://stackoverflow.com/questions/28403622/how-g-makes-loop-in-vim-ex-command-script Enviarme un mensaje si necesita más información. – Cong

2

Seleccionar las líneas de destino en el modo Visual, a continuación, ejecutar el comando Ex

:'<,'>s/^/\=(line('.')-line("'<")+1).' ' 
1

Aquí hay un truco sucio pero la vida se compone de estos. :)

ESC :r! for i in $(seq 1 10); do echo "This is line \#${i}"; done 

plataforma no cruzada.

24

En lugar de una construcción complicada, puede simplemente usar una macro con la función CTRL-a para incrementar un número inicial. Ejemplo de datos:

aaa 
bbb 
ccc 

insertar primero un número de inicio y un espacio:

1 aaa 
bbb 
ccc 

entonces registrar esta macro en la línea 1 (<C-a> significa prensa CTRL-a):

qq0yf 0j0P0<C-a>q 

Explicación:

  1. qq: Grabar macro en el registro q
  2. 0: ir a la primera columna.
  3. yf: tire todo hasta e incluyendo el primer espacio (recuerde que su primera línea tiene 1 y un espacio).
  4. 0jP: baje y pegue el patrón al comienzo de la línea.
  5. 0<C-a>: vaya a la primera columna e incremente el número en uno.
  6. q: grabación de macro final.

esto da:

1 aaa 
2 bbb 
ccc 

Ahora puede aplicar esta macro con @q todo el tiempo que desee. Si necesita un aumento de dos, simplemente use CTRL-aCTRL-a en lugar de solo una vez. Ahora puede aplicar esta macro a líneas consecutivas, por ejemplo:

:.,$norm @q 

agregará números de línea principal para el resto de su archivo.

+0

Si entiendo correctamente, está copiando el número anterior e incrementándolo. ¿Funciona si el número tiene más dígitos? ¿Hay alguna razón para el espacio entre 'f' y' 0'? –

+0

Sí, entiendes esto correctamente. El espacio es importante ya que copia cualquier cosa, incluido el espacio, con 'f', para que pueda copiar más dígitos. Así que sí, funciona para números con más de un dígito, simplemente lo intenté hasta la línea 1449 en un archivo :) Por supuesto que puede usar cualquier otro carácter de separación, me viene a la mente 'tab'. – hochl

+0

Ah sí. Por alguna razón, asumí que 0 significaba "número", por lo que f se habría movido al primer número. Creo que esta es la mejor solución aquí. –

8
:4,8s/^/\=line(".")-3." "  

va a hacer lo que quiere

si necesita contar = 2:

:4,8s/^/\=2*(line(".")-3)." " 

Esto le dará 2,4,6,8,10

números de línea son codificado en mi ejemplo, puede usar V para seleccionar las líneas que desea cambiar.

+0

Esto no funciona en vi pero funciona en vim. –

-1

A menos flexible, pero fácil de recordar método es usar un plugin renumeración como Renumber.vim http://www.vim.org/scripts/script.php?script_id=189

Si todavía no hay ningún número, al igual que en el PO, algún número se debe insertar en su lugar. Renumerar puede manejar el pedido real y lo hace en función del solo primer número.

En este ejemplo, estoy usando <C-v> para insertar el número inicial en todas las líneas que desea numerar.

4G<C-v>4jGI1 <Esc>gv:Renumber

Para utilizar etapas de dos

:Renumber s2

1

El plugin Nexus proporciona el tipo de la serie y un objeto, s1, de ese tipo que se utiliza de esta manera:

:4,8s/^/\=s1.next().' '/ 

Nexus también viene con un objeto de la serie s0 que arroja 0 como su primer resultado .next(). Tanto s0 como s1 usan un incremento de 1 paso. Todos los objetos de la serie tienen un método .reset() que los devuelve a su valor iniciado. Serie de objetos nuevos se pueden crear como la siguiente llamada:

let s2 = Series(0, 2) 

que crea un 2-Objeto de paso conocer a su segunda solicitud (rendimiento: 2, 4, 6, 8 ...)

1

Creo que todos las soluciones propuestas son demasiado difíciles de recordar, puede usarlas una sola vez, pero luego debe consultar todos los detalles cada vez que las use (si las usa menos de una vez al día).

Encontré el visual incrementing script realmente fácil de instalar y usar. Una vez que está instalado en vim, solo necesita generar una columna de 0, seleccionarla con Ctrl-V y escribir el comando: I. Luego generará automáticamente números crecientes en cada línea. También hay otras características:

  • comenzar con un número diferente de 0
  • números de la izquierda o hacia la derecha con 0 de (como 001, ..., 015)
  • disminuyendo o aumentando el número
  • aumento en más de 1
  • fechas (pero se necesita un plugin adicional), letras del alfabeto, dayNames

Esto resuelve un problema más general porque funciona también en una posición diferente a la columna 0, la columna tiene que ser seleccionable con Ctrl-V.

El vimball del plugin es here o here.

0

(si su vim tiene soporte Perl - por defecto en muchos sistributions Linux): Seleccionar las líneas en modo visual (V) y hacer

:perldo s/^/++$z . " "/e 
3

Con Vim 8,0 se puede utilizar g Ctrl-a, ver :help v_g_CTRL-A

Vaya a la línea n. ° 4, use CTRL-v para bloquear seleccione el primer carácter, presione I1 (hay un espacio después del 1) y Escape para salir del modo de inserción. El resultado se verá así:

this is line #1 
this is line #2 
this is line #3 
1 this is line #4 
1 this is line #5 
1 this is line #6 
1 this is line #7 
1 this is line #8 
this is line #9 
this is line #10 

Ahora usa Ctrl-v de nuevo para seleccionar todo inserta 1 excepto el primero. Presione g Ctrl-a para crear una secuencia.

this is line #1 
this is line #2 
this is line #3 
1 this is line #4 
2 this is line #5                  
3 this is line #6 
4 this is line #7 
5 this is line #8 
this is line #9 
this is line #1 

Uso 2g Ctrl-a utilizar un número de pasos de 2.

Cuestiones relacionadas