Suponiendo que su archivo tiene menos de 20,000 líneas, por supuesto :-)
paxdiablo
3
En realidad te equivocas Michael. Esto funciona perfectamente ya que VI dejará de ejecutar la macro tan pronto como llegue al final del archivo. Puede probarlo muy fácilmente con el ejemplo anterior.
rui
1
Bueno, como cualquier macro, debe hacerlo bien la primera vez, pero después puede aplicarla a cualquier archivo simplemente escribiendo 10000 @ q. De cualquier manera, creo que es solo una cuestión de gustos, así que definitivamente no voy a iniciar un debate filosófico. :)
rui
3
Prefiero usar 'macro'. Usando macro, usted 'describe' cómo resolvería una tarea en particular y deja que VIM la repita por usted. RUI, preferiría usar 'j' en lugar de la tecla de flecha.
Una forma elegante (y eficiente) de realizar la tarea es invocar el :+deletecomando eliminando la línea que sigue a la actual, en cada línea usando el :globalcomando:
¿Por qué esta respuesta no obtuvo más votos a favor? Esto es tan limpio y simple. Alternativamente, puede eliminar la primera línea y ejecutar el comando anterior para eliminar todas las líneas impares.
Usagi
3
@Usagi: ¡Gracias! Siento lo mismo al respecto. Y sí, tienes toda la razón, :1d|g/^/+dborra las líneas impares.
ib.
@Usagi La otra respuesta fue seleccionada como la 'mejor respuesta' 2 años antes de que apareciera su respuesta. Además, aunque esta es una solución más elegante, podría haberse escrito de una manera más útil (es decir, no se menciona lo que hace ^, mientras que la macro es fácil de entender para cualquiera).
user1271772
3
Lo siento, pero sin una explicación de cómo ese comando realiza el comportamiento deseado, no lo votaría y preferiría la respuesta aceptada, ya que entiendo cómo logra el objetivo. Es la diferencia entre darle un pescado a un hombre y enseñarle a pescar.
Gabe
3
No sé, esta respuesta me hizo salir y aprender a pescar con el comando: g (es decir, me hizo buscar en Google esta página - vim.wikia.com/wiki/Power_of_g ).
snetch
67
Podemos usar :normalo :normpara ejecutar determinados comandos de modo normal. Fuente.
Esta respuesta no recibe suficiente atención, posiblemente debido a la falta de explicación tanto aquí como en la hoja de trucos vinculada y desordenada. el comando norm ejecuta los comandos del modo normal equivalentes a las letras que le siguen. Entonces aquí está ejecutando j para moverse hacia abajo en una línea y dd para borrarlo. Esto se puede generalizar a la línea X al agregar más 'j's en este caso.
imoatama
5
y el% es la abreviatura de 1, $ (ejecute el siguiente comando desde la línea 1 hasta el final)
Lambart
3
Me interesa saber por qué %norm ddjno funciona si desea eliminar filas impares.
Cyker
10
: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.
Entonces prefiero !perl -ne 'print unless $. % 2':-)
Alex Brasetvik
Y, Alex, definitivamente preferiría mi solución a la tuya, pero vale la pena considerar esta, ya que es la única solución sensata que usa solo vim aquí.
Michael Krelin - hacker
La forma macro es mucho más fácil.
trusktr
1 debido a la flexibilidad con if (expression)la que también trabaja para cada tercera línea, etc
Jens
5
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)
No necesita el -lcambio a Perl ... también, yo diría que awkestá 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\%2o :%!awk 1-NR\%2para las otras líneas.
Correcto. Porque me olvidé de eso. ;-) Pero en realidad, la variante "adecuada" será aún más larga con NR. Y no habría dos homólogos atractivos .
Michael Krelin - hacker
:%!awk NR\%2o :%!awk 1-NR\%2, como publiqué en otro comentario. Eso es apenas más.
efímero
1
1-NRes 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í.
Michael Krelin - hacker
Y NRes más corto que ++c:)
efímero
3
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
El .,/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 gal final significa repetir la sustitución siempre que se siga encontrando la expresión regular.
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.
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 bes 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.
:% !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
Respuestas:
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.
fuente
: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:fuente
:1d|g/^/+d
borra las líneas impares.Podemos usar
:normal
o:norm
para ejecutar determinados comandos de modo normal. Fuente.fuente
%norm ddj
no funciona si desea eliminar filas impares.Aquí ^ significa CTRL. Macro recursiva para eliminar una línea cada dos líneas. Elige bien tu primera línea y listo.
fuente
desde el archivo de correo vim :
(Para escribir en una línea en la línea de comando de vim, eliminará la fila 1,3,5,7, ...)
fuente
!perl -ne 'print unless $. % 2'
:-)if (expression)
la que también trabaja para cada tercera línea, etcSiempre puede canalizar a través de un comando de shell, lo que significa que puede usar cualquier lenguaje de scripting que desee:
(o use "a menos que" en lugar de "si", según las líneas que desee)
fuente
-l
cambio a Perl ... también, yo diría queawk
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.alternativamente
dependiendo de la mitad que quieras eliminar.
fuente
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 quec++
. 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/
es el rango para la sustitución. Significa "de esta línea a la línea que coincide con la expresión regularfff
(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. Elg
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.
fuente
$
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.
b = cb[:]
copia temporalmente todas las líneas del búfer actual enb
.b[::2]
obtiene cada segunda línea del búfer y la asigna a todo el búfer actualcb[:]
. La copia enb
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.
fuente
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.
fuente
Invocar sed:
fuente
solución
puedes probar esto en vim
editar
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 desapareceSé que está embarrado, pero es vim y funciona
fuente