Tengo folderA
que 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_000750
hasta 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_0008
oa_0009
, ea_0007[5-9]*
incluye todos los archivos que comienzan cona_0007
y 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í,
find
simplemente enumera todos los archivos que coincidena_*
. La lista se pasa a unwhile
bucle 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) es000750
o mayor, el archivo se elimina. El-v
está 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
201
viene antes31
en lexicografía, no lo hace antes031
.Pruebe esto con el
echo
comando, y una vez que esté seguro de que enumera los archivos correctos, userm
en 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
bash
yksh
, sin embargo, no se puede usar en el/bin/sh
shell estándar , al que Ubuntu está vinculado/bin/dash
.En los casos en los que tiene que confiar
/bin/sh
para la portabilidad de sus scripts, generalmente hay dos formas de abordar esto. Uno sería a través de globbing. Justocd folderA
y desde allí correrm a_*
. La otra forma, sería implementar un estilo C para la alternativa de bucle usandowhile <CONDITION>;do ...done
lenguaje 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 hacd
editado 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
sprintf
función, y (2) eliminar dichos archivos mediante unsystem()
comando, que pasará nuestro nombre de archivo yrm
comando 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
...