¿Cómo invierto el orden de las líneas seleccionadas en Vim?


94

Por ejemplo, si tengo cuatro líneas de la siguiente manera:

la primera línea
la segunda línea
la tercera línea
la cuarta línea

Quiero revertirlos a

la cuarta línea
la tercera línea
la segunda línea
la primera línea

¿Cómo podría hacer esto en Vim?




1
:command! -bar -range=% Reverse <line1>,<line2>global/^/m<line1>-1 vi.stackexchange.com/a/2107/10254
qeatzy

Respuestas:


86

Para invertir todas las líneas en un archivo,

:g/^/m0

Para una explicación ver

:help 12.4

que también muestra cómo invertir solo un rango de líneas.


12
Gran consejo sobre la sección de ayuda exacta! Para resumir: 1. establezca un marcador en la última línea que desea revertir (llamo al marcador 'a' usando ma), 2. mueva el cursor a la primera línea del bloque, 3. escriba:'a,.g/^/m 'a
Brent Faust

69

Seleccione las líneas deseadas, presione !, y en el indicador resultante canalice las líneas a través de tacuna :'<,'>!tac. Ver man tacpara más detalles.


44
Para seleccionar las líneas, use shift+vpara ingresar al modo de línea visual, luego jpara agregar líneas a la selección.
wisbucky

¡Puedo confirmar que esto también funciona en Windows gvim! De lo contrario, debe usar números de línea absolutos (tal vez puede usar relativo, pero debe tener cuidado) con el :g/^/m0(que también es realmente difícil de recordar) ... Entonces, esencialmente, tac debe estar con vim sin importar qué plataforma estás en, PERO no es 100% vimscript, PERO a quién le importa: P
dylnmc

tac no es un manejo vim completamente nativo, pero el comando 'm'ove toma un número de línea y eso no siempre es razonable. A menudo uso una marca como parte de un rango, por lo que :.,'a!tacfunciona con un mínimo esfuerzo.
studog

Después de usar shift+v, puede usar }para llegar hasta el siguiente párrafo, o vaciar el espacio vertical. Además, man tac: concatenate and print files in reverse.
nilon

33

En Mac OS X, tacno existe, pero puede usarlo tail -rpara el mismo efecto:

:%!tail -r

Esto también funciona bien para el modo visual:

:'<,'>!tail -r

Extracto de tail(1)la página de manual de:

La opción -r hace que la entrada se muestre en orden inverso, por línea. Además, esta opción cambia el significado de las opciones -b, -c y -n. Cuando se especifica la opción -r, estas opciones especifican el número de bytes, líneas o bloques de 512 bytes para mostrar, en lugar de los bytes, líneas o bloques desde el principio o el final de la entrada desde la cual comenzar la visualización. El valor predeterminado para la opción -r es mostrar toda la entrada.


3
¡Excelente! Entonces, para proporcionar 'tac' en OS X:alias tac='tail -r'
Brent Faust

44
También puedes brew install coreutilsy usa gtac.
Andrew Marshall

1
Genio. Nunca pensé en usar! comandos para este tipo de manipulación de línea visual.
Charlie Dalsass

3

Para aquellos que se sienten más cómodos con el modo Visual:
1. Identifique el número de línea sobre la selección que desea voltear usando :set nu.
2. Shift-Vpara resaltar la selección que desea voltear (modo visual).
3 :g/^/m <Line number from step 1>..

Tenga en cuenta que en modo visual se mostrará automáticamente como :'<,'>g/^/m <Line number>cuando escribe el comando de 3.

Este comando funciona moviendo la selección una línea a la vez al número de línea que le da. Cuando el segundo elemento se inserta en el número de línea dado, empuja el primero hacia abajo hasta el número de línea + 1. Luego, el tercero empuja el primero y el segundo hacia abajo y así sucesivamente hasta que toda la lista ha sido empujada al número de línea único, lo que resulta en un lista de orden inverso.


44
Puede usar el en '<lugar de ingresar el número de línea manualmente. Simplemente comience la selección una línea antes y ejecute :'<,'>g/^/m'<.
Palec

3

Un comando :Rev[erse]y asignaciones opcionales para su vimrc, para que no tenga que recordar y realizar los pasos no obvios de esta receta:

" Reverse the lines of the whole file or a visually highlighted block.
    " :Rev is a shorter prefix you can use.
    " Adapted from http://tech.groups.yahoo.com/group/vim/message/34305
command! -nargs=0 -bar -range=% Reverse
    \       let save_mark_t = getpos("'t")
    \<bar>      <line2>kt
    \<bar>      exe "<line1>,<line2>g/^/m't"
    \<bar>  call setpos("'t", save_mark_t)

nmap <Leader>r :Reverse<CR>
xmap <Leader>r :Reverse<CR>

( :xmapasigna para el modo Visual pero no para Seleccionar, como se :help mapmode-xrecomienda para asignar caracteres imprimibles).

(Basado en: http://tech.groups.yahoo.com/group/vim/message/34305 )


Esta debería ser la respuesta aceptada de la OMI. Muy útil en general y no tengo que recordar :'<,'>g/^/m'<:)
Eliot

1
@Eliot, gracias! :) (Agregué un poco de 'contenido extra';))
Aaron Thoma el

¿Cómo puedo decir que la selección comienza -1 en este caso? Porque el movimiento comienza en este punto.
SergioAraujo

@SergioAraujo: ¿Es algo como :-1,+1Revlo que estás buscando? Sepa que usted puede seleccionar visualmente el rango que desea revertir, por ejemplo: V7j:Rev. Si eso no responde a su pregunta, no lo he entendido, por lo que necesitaría elaborarlo o reformularlo para mí.
Aaron Thoma

1

Digamos que está en la línea 3, por lo tanto, tenemos un rango de 3 a 6. Simplemente escriba.

:3,6g/^/m2

1
Puede dejar implícito el número de la línea actual: con el cursor en la primera línea de su rango, puede acortar a :,6g/^/m2; o cuando en la última línea de la gama: :3,g/^/m2; y :3,6g/^/m2funciona desde cualquier parte del archivo.
Aaron Thoma
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.