En primer lugar, siendo esta mi primera publicación aquí, me gustaría decir que he encontrado que VIM es una gran herramienta y que el foro aquí es muy útil para encontrar respuestas a las preguntas, con mucha gente útil invaluable asistencia. Todavía soy muy nuevo en VIM, por lo que casi todo lo que aprendí sobre él proviene de aquí.
Mi pregunta es: sé cómo invertir TODAS las líneas en un archivo (: g / ^ / m0 entre otras formas), pero ¿hay alguna manera de invertir cada 4 líneas en un archivo, de modo que
line1
line2
line3
line4
line5
line6
line7
line8
...
se convierte
line4
line3
line2
line1
line8
line7
line6
line5
...
Puede suponer que siempre habrá un múltiplo exacto de 4 líneas en dichos archivos.
Respuestas:
El comando
:Reverse
explicado en Vim Wiki se puede usar para esto (puede incluirlo en su.vimrc
para que sea permanente):Luego puede grabar una macro para ejecutar el comando en cada cuatro líneas:
Explicación:
qm
: 'q' en modo normal comienza (y detiene) la grabación de una macro en un registro dado (registro 'm', en este caso, pero podría ser cualquier otra letra)V
: ingrese al modo visual y seleccione la línea actual3j
: expande la selección visual a las siguientes 3 líneas:Reverse<cr>
: ejecuta el comando Invertir en las líneas seleccionadas (<cr>
aquí se encuentra la entertecla)4j
: ir a las siguientes líneas sin cambiosq
: deja de grabar la macro1000@m
: ejecute la macro grabada en el registro 'm' 1000 veces (puede aumentar este número si su archivo tiene más de 4000 líneas)Editar:
Como se menciona en los comentarios, puede usar una macro recursiva en lugar de usar un conteo:
qM
: si el registro especificado paraq
es mayúscula, la macro se agrega al registro (lo que también es útil cuando se da cuenta cuando omitió los últimos pasos en una macro compleja)@m
: ejecuta la macro en el registrom
q
: deja de agregar la macroA pesar de que se crea como una macro, puede crear un comando para esto si es una tarea común en su flujo de trabajo:
function! Reverse4()
/endfunction
: define una nueva funciónlet reg_m = @m
: guarda el contenido actual del registrom
let @m = "<c-r><c-r>m"
: inserte la macro en el registrom
; tenga en cuenta que<c-r>
es la notación vim para Ctrl+ ry que debe escribir esto, no copiar / pegar, por lo que su línea será similarlet @m = 'V3j:Reverse^M4j@m'
y contendrá un carácter especial (^ M)normal! @m
: el comando normal ejecuta su argumento como se ha escrito en modo normal, por lo que ejecutará la macro recursivalet @m = reg_m
: restaura el contenido del registrom
, por lo que no tiene que recordar que este registro se está utilizando en esta función y evitar usarlocommand! Reverse4 call Reverse4()
: crea un nuevo comando para esta funciónDependiendo de sus necesidades, podría mejorarlo, por ejemplo: pasar un argumento al comando y la función para que funcione para cualquier número de líneas en lugar de estar arreglado en grupos de 4 líneas.
fuente
1000@q
corte, también se puede utilizar una macro recursiva:qmqqm ... @mq@m
.command! -bar -range=% Reverse <line1>,<line2>g/^/m<line1>-1|nohl
en algún lugar de su vimrc.Al igual que con todas las acciones repetitivas , si puede hacer algo una vez con las operaciones básicas de edición, puede hacerlo fácilmente muchas veces grabando una macro.
(En este caso, usaré una macro recursiva, pero podría grabar una no recursiva y reproducirla varias veces martillando
@@
o usando un conteo).Desglosado
gg
: Ir al inicio del archivo.qqq
: Borrar registroq
. Veremos por qué esto es necesario en el paso 5.qq
: Comience a grabar una macro para registrar qddjjpkddkkPjddpjj
: Una serie de operaciones que reordena las primeras cuatro líneas simplemente borrándolas y pegándolas manualmente. (Esto puede parecer complicado a primera vista, pero no se deje engañar Esto es algo muy básico que habrías aprendido en los primeros 5 minutos o así de.vimtutor
:j
,k
,dd
,p
,P
)@q
: ¡Llama a la macro! En este punto, el registroq
no contiene nada (porque lo borramos en el paso 2), por lo que no sucederá nada.q
: Deja de grabar la macro.@q
: Reproduce la macro recursiva tantas veces como sea necesario.Nota: lo anterior no producirá los resultados deseados si el archivo contiene varias líneas que no son exactamente divisibles por cuatro. Para detener la macro antes de tiempo si no quedan cuatro líneas, debemos ejecutar un comando de modo normal de Vim que fallará, antes de comenzar a aplicar las ediciones en el paso 4. Podemos hacerlo intentando movernos hacia abajo una línea tres veces (y luego una copia de seguridad) antes de comenzar a mover líneas:
jjj3k
Así:
fuente
q
, debe estar vacía, de lo contrario, arruinará sus ediciones.qqqggqqjjjkddkkPjddjpkddkkPjjjj@qq@q
where I can just use the one-line custom command each time I need to do this
: tenga en cuenta que no tiene que volver a crear la macro cada vez que necesita usarla, ya que es posible almacenarla como una función / comando en su vimrc.También puede hacer esto con un
Ex
comando usandosed
como filtro externo:Esta versión ignorará (eliminará) cualquier línea adicional más allá de un múltiplo de 4. Para mantener el último conjunto de menos de 4 líneas (invertido), use:
El
%
aquí significa "Cada línea en el búfer".El
!
comando significa "Ejecutar el siguiente comando con las líneas especificadas como entrada y reemplazar las líneas especificadas con la salida del comando". (Se llama filtro; muy útil para cosas como ordenar, por ejemplo,:%!sort
ordenará todas las líneas en su archivo;:2,8!sort
ordenará las líneas 2-8, etc.)sed
es la herramienta de edición de flujo y se encuentra en todos los sistemas tipo Unix. Los conceptos clave de lossed
utilizados aquí son el "espacio de patrón" (que por defecto solo contiene cada línea de la entrada) y el "espacio de retención" (que es donde puede pegar texto adicional mientras lo usased
para guardarlo mientras procesa otros líneas de entrada).-n
es una opción delsed
comando para suprimir sus acciones predeterminadas de imprimir el espacio del patrón (porque en este caso solo queremos imprimir cuando lo decimos explícitamente).$p
en elsed
comando significa "Si está en la última línea desed
entrada, imprima (el espacio del patrón)".h
significa "pegar el contenido actual del 'espacio de patrón' en el 'espacio de espera', sobrescribiendo lo que esté allí".n
significa "reemplazar el contenido del 'espacio de patrón' con la siguiente línea de la entrada".G
significa "anexar al 'espacio de patrón': una nueva línea seguida por el contenido del 'espacio de retención'".En conjunto, el
sed
comando almacena cuatro líneas de salida, las invierte a medida que las almacena y luego las imprime. Los$p
comandos agregados en la segunda versión aseguran que si se alcanza la última línea del archivo que no sea en un múltiplo de 4 líneas, las líneas aún se imprimirán.Para un enfoque alternativo e interactivo aún sin usar ninguna característica específica de Vim y también sin usar un filtro externo:
para ir a la cuarta línea.
para invertir las cuatro líneas anteriores (1-4) y dejar el cursor en la línea 8.
.m -4
mueve la línea actual justo después de la línea cuatro líneas hacia atrás (dejando el cursor en la línea movida).+3m .
mueve la línea que está 3 líneas después de la línea actual, justo después de la línea actual, dejando el cursor en la línea movida.+2m .
por supuesto funciona igual.+5
coloca el cursor cinco líneas hacia abajo desde donde está.Repita como lo desee.
En Vim puede repetir todo este comando con
@:
, luego repetir nuevamente con@@
. En POSIXvi
oex
tendría que insertarlo:.m -4 | +3m . | +2m . | +5
como una línea de texto, eliminarlo en un búfer con nombre (registro) y luego ejecutar ese búfer con nombre (registro).Entonces, en
ex
modo, invierte líneas interactivamente usando solo características especificadas por POSIX, y comenzando con 17 líneas de texto:Otras lecturas:
ex
vi
fuente
4G:.m -4 | +3m . | +2m . | +5<Enter>@:
luego@@
repita hasta que su archivo esté completamente procesado. Sin embargo, recomiendo instalar MobaXterm. :)Inglés simple: para cada línea, mueva la línea actual hacia arriba
lnum % 4
, a menos quelnum % 4 == 0
, en cuyo caso, mueva la línea actual hacia arriba4
.Además, para invertir todas las
n
líneas, reemplace las4
's en el comando anterior conn
.fuente