Tengo folderAque tiene algunos archivos con una secuencia numérica que comienza con a_000000. Lo que quiero hacer es eliminar archivos a partir de un número específico: digamos a_000750hasta el final de los archivos en esto folderA. ¿Alguien podría aconsejar cómo hacer esto usando el script de shell?
16

rm a_000[89]* a_0007[5-9]*?a_000[89]*incluye todos los archivos que comienzan cona_0008oa_0009, ea_0007[5-9]*incluye todos los archivos que comienzan cona_0007y luego contienen un número entre 5 y 9, seguido de cualquier cosa.Respuestas:
Suponiendo que sabe o puede adivinar el final del rango, puede usar expansiones de llaves :
Lo anterior eliminará los 101 archivos entre a_000750 y a_000850 inclusive (y se quejará de los nombres de archivo que se refieren a archivos no existentes). Si tiene demasiados archivos para eso, use
find:Aquí,
findsimplemente enumera todos los archivos que coincidena_*. La lista se pasa a unwhilebucle donde cada nombre de archivo se lee en la variable$file. Luego, utilizando las funciones de manipulación de cadenas de bash , si la parte numérica (buscar imprime los archivos como./file, por lo que solo${file#./a_}imprime el número) es000750o mayor, el archivo se elimina. El-vestá ahí para que pueda ver qué archivos se han eliminado.Tenga en cuenta que lo anterior supone nombres de archivo sanos. Si sus nombres pueden tener espacios, líneas nuevas u otros caracteres extraños, use esto en su lugar:
fuente
[[?[[no simplifica las cosas aquí,[[ "${file#./a_}" > 000749 ]]por ejemplo, ni siquiera lo hace más corto. No me gusta usar sintaxis innecesaria y esta incluso funcionará en shells más simples comodash.[[maneja mejor los espacios y las rarezas (tampoco me importan demasiado>).[está bien si cita la variable como yo, funciona en muchos más shells y es más simple.Podrías hacer algo como esto:
O:
El primer método asume un prefijo fijo, lo elimina y verifica el valor.
El segundo método supone un sufijo de longitud fija (y un prefijo fijo común) y se basa en ese hecho; y que, aunque
201viene antes31en lexicografía, no lo hace antes031.Pruebe esto con el
echocomando, y una vez que esté seguro de que enumera los archivos correctos, usermen su lugar.fuente
Solución de shell POSIX
La primera solución de terdon se basa en la expansión de llaves , que es una propiedad de
bashyksh, sin embargo, no se puede usar en el/bin/shshell estándar , al que Ubuntu está vinculado/bin/dash.En los casos en los que tiene que confiar
/bin/shpara la portabilidad de sus scripts, generalmente hay dos formas de abordar esto. Uno sería a través de globbing. Justocd folderAy desde allí correrm a_*. La otra forma, sería implementar un estilo C para la alternativa de bucle usandowhile <CONDITION>;do ...donelenguaje de shell y formatear los números conprintf:Tenga en cuenta que aquí lo uso
echo. Reemplaceecho "$filename"conrm ./"$filename"orm -- "$filename"cuando esté listo para eliminar los archivos. También tenga en cuenta que esto debe realizarse cuando ya hacdeditado en el directorio deseado.(ab) usando awk
Awk es un buen lenguaje tipo C que puede ayudarnos de dos maneras: (1) podemos generar nombres de archivo con for-loop y formatearlos mediante la
sprintffunción, y (2) eliminar dichos archivos mediante unsystem()comando, que pasará nuestro nombre de archivo yrmcomando generados a/bin/sh:Perl
Continuando con la idea del enfoque portátil donde "generamos" nombres de archivo, podemos hacer lo mismo en Perl:
fuente
Tan simple como
En tu ejemplo es
fuente
a_00075...