2012-07-23 9 views
5

que había utilizado previamente un simple comando find para eliminar el alquitrán no los archivos accedidos en los últimos X días (en este ejemplo, 3 días):escritura del golpe para limitar el tamaño del directorio y borrar los archivos que se accede última

find /PATH/TO/FILES -type f -name "*.tar" -atime +3 -exec rm {} \; 

Ahora necesito mejorar este script eliminando en orden de fecha de acceso y mis habilidades de escritura bash están un poco oxidadas. Esto es lo que se tiene que hacer:

  1. comprobación del tamaño de un directorio/ruta/a/ARCHIVOS
  2. si el tamaño en 1) es mayor que el tamaño X, obtener una lista de los archivos por fecha de acceso
  3. borrar archivos en orden hasta que el tamaño es menor que X

la ventaja aquí es para la memoria caché y de respaldo directorios, sólo borrará lo que necesito para mantenerla dentro de un límite, mientras que el método simplificado podría ir límite de tamaño si un día es particularmente grande. Supongo que necesito usar stat y bash para loop.

Respuesta

4

Aquí es un simple, fácil de leer y entender el método que se me ocurrió hacer esto:

DIRSIZE=$(du -s /PATH/TO/FILES | awk '{print $1}') 
if [ "$DIRSIZE" -gt "$SOMELIMIT" ] 
    then 
    for f in `ls -rt --time=atime /PATH/TO/FILES/*.tar`; do 
    FILESIZE=`stat -c "%s" $f` 
    FILESIZE=$(($FILESIZE/1024)) 

    DIRSIZE=$(($DIRSIZE - $FILESIZE)) 
    if [ "$DIRSIZE" -lt "$LIMITSIZE" ]; then 
     break 
    fi 
done 
fi 
+1

Creo que este script es un buen comienzo, pero en realidad no responde la pregunta. Usted preguntó cómo eliminar los archivos en orden para que el tamaño del directorio caiga por debajo del umbral. Su respuesta aquí no parece eliminar realmente nada, simplemente clasifica los archivos y hace un bucle a través de ellos. Parece que te estás perdiendo una "rm" aquí en alguna parte. –

1

No necesité utilizar loops, solo una aplicación cuidadosa de stat y awk. Los detalles y la explicación más abajo, primero el código:

find /PATH/TO/FILES -name '*.tar' -type f \ 
| sed 's/ /\\ /g' \ 
| xargs stat -f "%a::%z::%N" \ 
| sort -r \ 
| awk ' 
    BEGIN{curSize=0; FS="::"} 
    {curSize += $2} 
    curSize > $X_SIZE{print $3} 
    ' 
| sed 's/ /\\ /g' \ 
| xargs rm 

Tenga en cuenta que esta es una línea de comando lógico, pero por el bien de la cordura que divide hacia arriba.

Comienza con un comando de búsqueda basado en el anterior, sin las partes que lo limitan a archivos de más de 3 días. Lo canaliza a sed, para escapar de cualquier espacio en los nombres de los archivos encuentra devoluciones, luego usa xargs para ejecutar stat en todos los resultados. El -f "% a ::% z ::% N" indica el formato que se debe usar, con la hora del último acceso en el primer campo, el tamaño del archivo en el segundo y el nombre del archivo en el tercero. Usé '::' para separar los campos porque es más fácil tratar los espacios en los nombres de los archivos de esa manera. Ordenar los ordena en el primer campo, con -r para invertir el orden.

Ahora tenemos una lista de todos los archivos que nos interesan, en orden desde los últimos accesos hasta los más antiguos. Luego, el script awk suma todos los tamaños a medida que pasa por la lista y comienza a generarlos cuando supera los $ X_SIZE. Los archivos que no se muestran de esta manera serán los que se guardan, los otros nombres de archivo van a sed nuevamente para escapar de cualquier espacio y luego a xargs, que los ejecuta a ellos.

+0

Esta solución no funcionó. Mejoré el guión y publiqué el resultado como una respuesta separada. –

+0

La idea fue genial. Gracias. –

6

que mejoraron el ejemplo de brunner314 y se fijaron los problemas en ella.

Aquí es un script de trabajo que estoy usando:

#!/bin/bash 
DELETEDIR="$1" 
MAXSIZE="$2" 
if [[ -z "$DELETEDIR" || -z "$MAXSIZE" || "$MAXSIZE" -lt 1 ]]; then 
    echo "usage: $0 [directory] [maxsize in megabytes]" >&2 
    exit 1 
fi 
find "$DELETEDIR" -type f -printf "%[email protected]::%p::%s\n" \ 
| sort -rn \ 
| awk -v maxbytes="$((1024 * 1024 * $MAXSIZE))" -F "::" ' 
    BEGIN { curSize=0; } 
    { 
    curSize += $3; 
    if (curSize > maxbytes) { print $2; } 
    } 
    ' \ 
    | tac | awk '{printf "%s\0",$0}' | xargs -0 -r rm 
# delete empty directories 
find "$DELETEDIR" -mindepth 1 -depth -type d -empty -exec rmdir "{}" \; 
Cuestiones relacionadas