¿Cómo eliminar varios archivos a la vez en Bash en Linux?

103

Tengo esta lista de archivos en un servidor Linux:

abc.log.2012-03-14
abc.log.2012-03-27
abc.log.2012-03-28
abc.log.2012-03-29
abc.log.2012-03-30
abc.log.2012-04-02
abc.log.2012-04-04
abc.log.2012-04-05
abc.log.2012-04-09
abc.log.2012-04-10

He estado eliminando los archivos de registro seleccionados uno por uno, usando el comando que se rm -rfmuestra a continuación:

rm -rf abc.log.2012-03-14
rm -rf abc.log.2012-03-27
rm -rf abc.log.2012-03-28

¿Existe otra forma de eliminar los archivos seleccionados a la vez?

usuario1253847
fuente
4
Y "Di GNU / Linux, no solo Linux", escucho a alguien tronar desde los asientos traseros.
Boris Stitnicky
8
Por cierto, ¿por qué el -rf? ¿Son estas carpetas? f es forzar, r es recursivo. Funcionará si es solo un archivo, pero tenga en cuenta que usar -rf cada vez que desee eliminar algo es muy (muy) (muy muy) peligroso. (y debe agregar la etiqueta "bash" porque "linux" es demasiado ancho.
Depado
@BorisStitnicky - Tengo curiosidad por saber por qué GNUse necesita.
user66001
2
@ user66001: Para la opinión del proyecto GNU al respecto: gnu.org/gnu/linux-and-gnu.html . No tomo posición al respecto, al menos aquí, y este no es el lugar para debatirlo.
Keith Thompson
2
@BorisStitnicky - No hay necesidad de debatir, no tenía ni idea, y ese enlace me dio el nivel de información que estaba buscando +1
user66001

Respuestas:

159

Bash admite todo tipo de comodines y expansiones.

Su caso exacto se manejaría mediante la expansión de llaves , así:

$ rm -rf abc.log.2012-03-{14,27,28}

Lo anterior se expandiría a un solo comando con los tres argumentos y sería equivalente a escribir:

$ rm -rf abc.log.2012-03-14 abc.log.2012-03-27 abc.log.2012-03-28

Es importante tener en cuenta que esta expansión la realiza el shell, rmincluso antes de que se cargue.

relajarse
fuente
No use "rm" si desea restaurar los archivos en el futuro. Puede usar la utilidad "rm-trash": github.com/nateshmbhat/rm-trash
Natesh bhat
75

Utilice un comodín ( *) para hacer coincidir varios archivos.

Por ejemplo, el siguiente comando eliminará todos los archivos con nombres que comiencen con abc.log.2012-03-.

rm -f abc.log.2012-03-*

Recomendaría ejecutar ls abc.log.2012-03-*para enumerar los archivos para que pueda ver lo que va a eliminar antes de ejecutar el rmcomando.

Para obtener más detalles, consulte la página del manual de Bash sobre la expansión del nombre de archivo .

dogbane
fuente
Muy útil, pero no pide confirmación para borrar. Por favor tenga cuidado.
nuriselcuk
1
@nuriselcuk, puede agregar -i para obtener la confirmación de cada archivo que se elimina.
Felipe Romero
Funcionó como un encanto en AWS Ec2-Instance con Amazon Linux 1 :) Gracias.
Kyle Bridenstine
41

Si desea eliminar todos los archivos cuyos nombres coinciden con una forma en particular, un comodín (patrón global) es la solución más sencilla. Algunos ejemplos:

$ rm -f abc.log.*             # Remove them all
$ rm -f abc.log.2012*         # Remove all logs from 2012
$ rm -f abc.log.2012-0[123]*  # Remove all files from the first quarter of 2012

Las expresiones regulares son más poderosas que los comodines; puede alimentar la salida de grepa rm -f. Por ejemplo, si algunos de los nombres de archivo comienzan con "abc.log"y otros con "ABC.log", le greppermite hacer una coincidencia que no distinga entre mayúsculas y minúsculas:

$ rm -f $(ls | grep -i '^abc\.log\.')

Esto causará problemas si alguno de los nombres de archivo contiene caracteres divertidos, incluidos espacios. Ten cuidado.

Cuando hago esto, ls | grep ...primero ejecuto el comando y verifico que produce el resultado que quiero, especialmente si estoy usando rm -f:

$ ls | grep -i '^abc\.log\.'
(check that the list is correct)
$ rm -f $(!!)

donde se !!expande al comando anterior. O puedo escribir la flecha hacia arriba o Ctrl-P y editar la línea anterior para agregar el rm -fcomando.

Esto supone que estás usando el shell bash. Es posible que algunos otros shells, particularmente csh y tcsh y algunos shells antiguos derivados de sh, no admitan la $(...)sintaxis. Puede utilizar la sintaxis de comillas invertidas equivalente:

$ rm -f `ls | grep -i '^abc\.log\.'`

La $(...)sintaxis es más fácil de leer y, si eres realmente ambicioso, se puede anidar.

Finalmente, si el subconjunto de archivos que desea eliminar no se puede expresar fácilmente con una expresión regular, un truco que uso a menudo es enumerar los archivos en un archivo de texto temporal y luego editarlo:

$ ls > list
$ vi list   # Use your favorite text editor

Luego puedo editar el listarchivo manualmente, dejando solo los archivos que quiero eliminar, y luego:

$ rm -f $(<list)

o

$ rm -f `cat list`

(Nuevamente, esto supone que ninguno de los nombres de archivo contiene caracteres divertidos, particularmente espacios).

O, al editar el listarchivo, puedo agregar rm -f al principio de cada línea y luego:

$ . ./list

o

$ source ./list

La edición del archivo también es una oportunidad para agregar comillas cuando sea necesario, por ejemplo, cambiar rm -f foo bara rm -f 'foo bar'.

Keith Thompson
fuente
8

Simplemente use la selección de varias líneas en sublime para combinar todos los archivos en una sola línea y agregue un espacio entre cada nombre de archivo y luego agregue rmal principio de la lista. Esto es principalmente útil cuando no hay un patrón en los nombres de archivo que desea eliminar.

[$]> rm abc.log.2012-03-14 abc.log.2012-03-27 abc.log.2012-03-28 abc.log.2012-03-29 abc.log.2012-03-30 abc.log.2012-04-02 abc.log.2012-04-04 abc.log.2012-04-05 abc.log.2012-04-09 abc.log.2012-04-10
Andy
fuente
Esta debería ser la respuesta aceptada, ya que responde explícitamente a la pregunta planteada. Es más amigable para las personas que vinieron aquí desde Google.
ATLief
5

Un comodín funcionaría bien para esto, aunque para estar seguro, sería mejor hacer el uso del comodín lo más mínimo posible, así que algo parecido a esto:

rm -rf abc.log.2012-*

Aunque por lo que parece, ¿son solo archivos únicos? La opción recursiva no debería ser necesaria si ninguno de esos elementos son directorios, así que es mejor no usar eso, solo por seguridad.

lacrosse1991
fuente
2

No soy un gurú de Linux, pero creo que desea canalizar su lista de archivos de salida a xargs rm -rf. He usado algo como esto en el pasado con buenos resultados. ¡Pruebe primero en un directorio de muestra!

EDITAR: es posible que haya entendido mal, según las otras respuestas que aparecen. Si puedes usar comodines, genial. Supuse que la lista original que mostrabas fue generada por un programa para darte tu "selección", así que pensé que la canalización xargssería el camino a seguir.

Dave
fuente
-1

si desea eliminar todos los archivos que pertenecen a un directorio a la vez. Por ejemplo: el nombre de su directorio es "log" y el directorio "log" incluye archivos abc.log.2012-03-14, abc.log.2012-03-15, ... etc. Tienes que estar encima del directorio de registro y:

rm -rf /log/*
Alican
fuente