Cómo hacerlo en Vim:
ANTES DE:
aaa
bbb
ccc
ddd
eee
fff
DESPUÉS:
aaa
ccc
eee
Puedes usar una macro para esto. Haz lo siguiente.
gg
.qq
.dd
después.q
.10000@q
PD: Para ir al modo de comando, simplemente presione Escape un par de veces.
:g/^/+d
from user stackoverflow.com/users/254635/ib (abajo) es una forma más elegante de resolver esto.
Una forma elegante (y eficiente) de realizar la tarea es invocar el :+delete
comando eliminando la línea que sigue a la actual, en cada línea usando el :global
comando:
:g/^/+d
:1d|g/^/+d
borra las líneas impares.
Podemos usar :normal
o :norm
para ejecutar determinados comandos de modo normal. Fuente.
:%norm jdd
%norm ddj
no funciona si desea eliminar filas impares.
:map ^o ddj^o
^o
Aquí ^ significa CTRL. Macro recursiva para eliminar una línea cada dos líneas. Elige bien tu primera línea y listo.
desde el archivo de correo vim :
:let i=1 | while i <= line('$') | if (i % 2) | exe i . "delete" | endif | let i += 1 | endwhile
(Para escribir en una línea en la línea de comando de vim, eliminará la fila 1,3,5,7, ...)
!perl -ne 'print unless $. % 2'
:-)
if (expression)
la que también trabaja para cada tercera línea, etc
Siempre puede canalizar a través de un comando de shell, lo que significa que puede usar cualquier lenguaje de scripting que desee:
:%!perl -nle 'print if $. % 2'
(o use "a menos que" en lugar de "si", según las líneas que desee)
-l
cambio a Perl ... también, yo diría que awk
está un poco más extendido que Perl, aunque en realidad no es mucho más en estos días, y puede hacer esto más corto: :%!awk NR\%2
o :%!awk 1-NR\%2
para las otras líneas.
:%!awk -- '++c\%2'
alternativamente
:%!awk -- 'c++\%2'
dependiendo de la mitad que quieras eliminar.
NR
variable existente ?
:%!awk NR\%2
o :%!awk 1-NR\%2
, como publiqué en otro comentario. Eso es apenas más.
1-NR
es más largo que c++
. Sí, sé que es un personaje. Como dije, la verdadera razón es que lo olvidé. De todos modos, parece que la gente no aprecia la belleza de awk aquí.
NR
es más corto que ++c
:)
Puede usar las capacidades de búsqueda y sustitución de Vim de esta manera: coloque el cursor en la primera línea y escriba en modo normal:
:.,/fff/s/\n.*\(\n.*\)/\1/g
.,/fff/
es el rango para la sustitución. Significa "de esta línea a la línea que coincide con la expresión regular fff
(en este caso, la última línea).s///
es el comando sustituto. Busca una expresión regular y reemplaza cada aparición de ella con una cadena. El g
al final significa repetir la sustitución siempre que se siga encontrando la expresión regular.\n.*\(\n.*\)
coincide con una línea nueva, luego una línea completa ( .*
coincide con cualquier número de caracteres excepto una línea nueva), luego otra línea nueva y otra línea. Los paréntesis \(
y \)
hacen que se registre la expresión dentro de ellos, para que podamos usarlo más tarde usando \1
.\1
inserta la nueva línea agrupada y la línea posterior de nuevo, porque no queremos que la siguiente línea desaparezca también; solo queremos que el mecanismo de sustitución pase por ella para no eliminarla en el próximo reemplazo.De esta manera, puede controlar el rango en el que desea que se realice la eliminación y no tiene que usar ninguna herramienta externa.
$
lugar de /fff/
, para el final del archivo, independientemente del contenido del archivo.
Como otro enfoque, también puede usar python si su vim lo admite.
:py import vim; cb = vim.current.buffer; b = cb[:]; cb[:] = b[::2]
b = cb[:]
copia temporalmente todas las líneas del búfer actual en b
. b[::2]
obtiene cada segunda línea del búfer y la asigna a todo el búfer actual cb[:]
. La copia en b
es necesaria ya que los objetos de búfer no parecen admitir la sintaxis de segmento extendida.
Probablemente esta no sea la "forma vim", pero podría ser más fácil de recordar si conoce Python.
Para borrar líneas impares (1,3,5, ..) -> :%s/\(.*\)\n\(.*\)\n/\2\r/g
Para borrar líneas pares (2,4,6, ..) -> :%s/\(.*\)\n.*\n/\1\r/g
Busque texto (forma la primera línea) seguido de un carácter de nueva línea y algo más de texto (forma la segunda línea) seguido de otro carácter de nueva línea y reemplace lo anterior con la primera coincidencia (línea impar) o la segunda coincidencia (línea par) seguido de retorno de carro.
Invocar sed:
:% !sed -e '2~2 d'
^^^^ pipe file through a shell command
^^^^^^ the command is sed, and -e describes an expression as parameter
^^^^^ starting with the second line, delete every second line
puedes probar esto en vim
:1,$-1g/^/+1d
Intentaré ser más claro (dos partes)
primera parte el rango de selección ( :from,to
)
segunda parte la acción ( d
borrar)
:1,$-1
)g
) delete ( +1d
) siguiente líneapuede intentar moverse a la primera línea de su archivo y ejecutar :+1d
, verá que la siguiente línea desaparece
Sé que está embarrado, pero es vim y funciona