¿Cómo puedo invertir el orden de las líneas para que la primera línea aparezca al final y la última línea aparezca primero? (Podrían ser todas las líneas en un búfer, un rango de direcciones o una selección de modo visual lineal).
Me gustaria transformar
rat
ox
tiger
⋮
dog
pig
dentro
pig
dog
⋮
tiger
ox
rat
sin recurrir a un comando externo como tac
.
rearrangement
200_success
fuente
fuente
Respuestas:
El poder de lo global funcionará aquí:
O, más simplemente (gracias @tommcdo)
El primero coincidirá con cada línea y para cada línea, elimínelo y péguelo en la parte superior del archivo. A medida que se mueve por el archivo, invierte el texto.
El segundo coincide de manera similar con cada línea y la mueve a la parte superior del archivo.
Nota: Ambos funcionan en todo el archivo y no se aplicarán correctamente para invertir un subconjunto de líneas. Vea la respuesta de Ingo Karkat para una solución que funciona dentro de un rango.
Descripción:
g
el comando global/^/
coincide con cualquier línea que tenga un comienzo (es decir, todas las líneas)exe
ejecute la siguiente cadena"normal
realice los comandos en modo normaldd
elimine la líneagg
mueva a la parte superior del archivoP
pegue por encima de la posición actualmove 0
mueve la línea actual a debajo de la línea 0 (que la coloca en la posición 1 o la primera línea del archivo)fuente
:normal
comando, podemos usar el comando Ex:move 0
, que mueve la línea al comienzo del búfer.:execute
solo es necesario cuando el comando debe construirse dinámicamente, por ejemplo:execute 'normal' g:user_command
.:execute
porque a menudo termino agregando otros comandos Ex después del existente más tarde, y es más conveniente para mí tener el:exe
allí ya que tener que volver e insertarlo más tarde. Desafortunadamente, ese hábito se filtró en esta respuesta donde no se aplica tanto.:execute
: dado que toma una cadena, proporciona una delimitación clara de dónde terminan los comandos en modo normal, aunque no estoy construyendo la cadena, es más fácil para mí encontrar comillas equilibradas que buscar<esc>
o lo que sea para terminar el modo. Nuevamente, esto es preferencia personal y hábito. :-):9,11g/^/move 8
... El último número debe ser el comienzo del rango menos 1 (adaptado de la respuesta de Ingo).Esta línea (para su
~/.vimrc
) define un:Reverse
comando; También puede usar la:global
parte directamente, pero la sintaxis de:move
(que desplaza iterativamente las líneas antes del comienzo del rango, invirtiéndola) no es fácil de memorizar:fuente
<line1>
&<line2>
están obligados a hacer que esto funcione en un rango, es decir::7,9Reverse
(son características decommand
, noglobal
omove
). El más simple:command! -bar -range=% Reverse :global/^/m 0
también funcionará, pero solo para todo el búfer ...Vim puro:
Explicación:
Fuente: Invierte todas las líneas y potencia de g en vim wikia.
Pocos ejemplos con comandos externos:
tac
(parte de GNU coreutils -cat
invertido):tail
en BSD / OSX (no compatible con POSIX):Para más ideas, ver:
fuente
:g/^/m0
mismo que:g/^/move 0
, cuál es la respuesta de John?tac
). Pero sospecho que el voto negativo se debió a que la respuesta se repitió.tac
OP lo mencionó, pero todas las demás preguntas similares serían duplicadas de todos modos, por lo que es bueno mencionarlo nuevamente. John tomó este cmd del comentario de @tommcdo, lo tomé inicialmente de DerMike , pero creo que lo tomó simplemente de wikia, así que le di créditos a vim wikia, por lo que no está completamente duplicado ya que la explicación es completamente diferente.En el espíritu de VimL funcional:
getline(1, line('$'))
devuelve una lista de todas las líneas en el búfer.'$'
es un argumento especial para elline()
que indica la última línea en el búfer.reverse(...)
invierte la lista de entrada, en el lugar.reverse(copy(...))
Debería usarse si la lista de entrada no se debe modificar.setline(1, ...)
reemplaza la línea especificada con el segundo argumento. Cuando el segundo argumento es una lista, el mismo número de líneas que la longitud de la lista se reemplaza con el contenido de la lista.Si lo desea, también puede definir un comando que tome un rango (
%
búfer completo predeterminado )fuente
hlsearch
está habilitado) como el:g/
comando de las otras respuestas ... ¿Sin embargo, el rendimiento es quizás peor? Comogetline(1, line('$'))
obtiene todo el búfer en la memoria.reverse()
parece estar en su lugar, por lo que debería tener muy poca memoria como tal ...Según la documentación de Vim usr_12.txt - Trucos inteligentes
fuente
Usando números relativos. El párrafo comienza en la línea 13 y abarca más 4 líneas.
fuente