¿Cómo elimino varios archivos con un prefijo y sufijo comunes?

21

Tengo muchos archivos llamados

sequence_1_0001.jpg  
sequence_1_0002.jpg  
sequence_1_0003.jpg  
...

y archivos llamados

sequence_1_0001.hmf  
sequence_1_0002.hmf  
sequence_1_0003.hmf  
...

y archivos llamados

sequence_2_0001.jpg  
sequence_2_0002.jpg  
sequence_2_0003.jpg  
...

y

sequence_2_0001.hmf  
sequence_2_0002.hmf  
sequence_2_0003.hmf  
...

Solo quiero eliminar los archivos que comienzan con 'secuencia_1' y terminan en '.hmf', pero no quiero eliminarlos uno por uno, ya que hay miles de archivos. ¿Cómo puedo especificar al comando rm que deseo eliminar todo lo que comienza con el prefilx 'secuencia_1' y termina en '.hmf'?

Actualmente estoy trabajando con un sistema RedHat Linux, pero también me gustaría saber cómo hacerlo en otras distribuciones.

Paul
fuente

Respuestas:

28
rm sequence_1*.hmf

elimina archivos que comienzan sequence_1y terminan en .hmf.


Globbing es el proceso en el que su shell toma un patrón y lo expande en una lista de nombres de archivo que coinciden con ese patrón. No lo confunda con expresiones regulares, que es diferente. Si pasa la mayor parte de su tiempo bash, Wooledge Wiki tiene una buena página sobre globbing (expansión de nombre de ruta) . Si desea la máxima portabilidad, también querrá leer la especificación POSIX sobre coincidencia de patrones / en su lugar.


En el improbable caso de que se encuentre con un error de "Lista de argumentos demasiado larga" , puede echar un vistazo a BashFAQ 95 , que aborda esto. La solución más simple es dividir el patrón global en múltiples fragmentos más pequeños, hasta que el error desaparezca. En su caso, probablemente podría salirse con la división de la coincidencia por dígitos de prefijo 0 a 9, de la siguiente manera:

for c in {0..9}; do rm sequence_1_"$c"*.hmf; done
rm sequence_1*.hmf  # catch-all case
jw013
fuente
Este es un trabajo muy inteligente en torno al error 'lista de argumentos demasiado larga' En mi caso, tengo veinte mil archivos, así que supongo que tendría que usar un bucle for de 0, ..., 20. ¿Correcto?
Paul
@Paul Correcto, solo divide la lista en tantos fragmentos como necesites, aunque en algún momento el findenfoque se vuelve más fácil de adivinar y verificar.
jw013
14

Si bien la respuesta de jw013 es correcta wrt globbing, ese comando puede fallar si tiene miles de coincidencias: la línea de comando expandida rm sequence_1_0001.hmf sequence_1_0002.hmf ...generada por el shell puede ser simplemente demasiado grande.

Como Dom sugirió, también puede usar la -deleteopción con find:

find . -maxdepth 1 -type f -name 'sequence_1*.hmf' -delete

Ambos -maxdepthy -delete, aunque no están en el estándar POSIX, son bastante comunes en findimplementaciones en la naturaleza. Las distribuciones de Linux generalmente usan GNU find, que ciertamente admite esas opciones.

Inútil
fuente
2
Si puede, use la opción -delete para buscar, no se bifurca para cada archivo ...
Dom
Añadido, saludos. Parece que -deletedebería ser compatible con los sistemas GNU y BSD recientes , mientras que solo -print0es GNU. Por lo tanto, es probable que sea más portátil también (aunque no debería hacer una diferencia para el OP).
Inútil
Al menos, el hallazgo de OS X tiene -print0, pero no está incluido en POSIX.
Lri
5
rm sequence_1_{0000..0999}.hmf
rm sequence_1_{1000..1999}.hmf
rm sequence_1_{2000..2999}.hmf
...

funcionaría también en Bash.

usuario desconocido
fuente
La expansión de llaves requiere bash, y la forma de relleno cero necesita la versión 4, creo.
jw013