linux - por - script para borrar archivos de una carpeta
Script de Shell para contar archivos, luego eliminar archivos más antiguos (10)
Asegúrese de que su pwd sea el directorio correcto para eliminar los archivos (suponiendo solo caracteres normales en el nombre del archivo):
ls -A1t | tail -n +11 | xargs rm
mantiene los últimos 10 archivos. Utilizo esto con el "movimiento" del programa de la cámara para mantener los archivos de captura de fotogramas más recientes. Gracias a todas las respuestas anteriores porque me enseñaste cómo hacerlo.
Soy nuevo en shell scripting, así que necesito ayuda aquí. Tengo un directorio que se llena con copias de seguridad. Si tengo más de 10 archivos de copia de seguridad, me gustaría eliminar los archivos más antiguos, de modo que los 10 archivos de copia de seguridad más nuevos sean los únicos que quedan.
Hasta ahora, sé cómo contar los archivos, lo que parece bastante fácil, pero ¿cómo puedo eliminar los archivos más antiguos, si el recuento es superior a 10?
if [ls /backups | wc -l > 10]
then
echo "More than 10"
fi
Contador de archivos directo:
max=12
n=0
ls -1t *.dat |
while read file; do
n=$((n+1))
if [[ $n -gt $max ]]; then
rm -f "$file"
fi
done
En un entorno de chroot muy limitado, solo teníamos un par de programas disponibles para lograr lo que inicialmente se pedía. Lo solucionamos de esa manera:
MIN_FILES=5
FILE_COUNT=$(ls -l | grep -c ^d )
if [ $MIN_FILES -lt $FILE_COUNT ]; then
while [ $MIN_FILES -lt $FILE_COUNT ]; do
FILE_COUNT=$[$FILE_COUNT-1]
FILE_TO_DEL=$(ls -t | tail -n1)
# be careful with this one
rm -rf "$FILE_TO_DEL"
done
fi
Explicación:
-
FILE_COUNT=$(ls -l | grep -c ^d )
cuenta todos los archivos en la carpeta actual. En lugar de grep, podríamos usar tambiénwc -l
pero wc no estaba instalado en ese host. -
FILE_COUNT=$[$FILE_COUNT-1]
actualiza el$FILE_COUNT
actual -
FILE_TO_DEL=$(ls -t | tail -n1)
Guarda el nombre de archivo más antiguo en la variable$FILE_TO_DEL
.tail -n1
devuelve el último elemento de la lista.
Experimenta con esto, porque no estoy 100% seguro de que funcione:
cd /backups; ls -at | tail -n +10 | xargs -I{} "rm ''{}''"
La forma correcta de hacer este tipo de cosas es con logrotate
.
Me gustan las respuestas de @Dennis Williamson y @Dale Hagglund. (+1 a cada uno)
Aquí hay otra forma de hacerlo usando find
(con la prueba -newer
) que es similar a lo que comenzó.
Esto fue hecho en Bash on Cygwin ...
if [[ $(ls /backups | wc -l) > 10 ]]
then
find /backups ! -newer $(ls -t | sed ''11!d'') -exec rm {} /;
fi
Prueba esto:
ls -t | sed -e ''1,10d'' | xargs -d ''/n'' rm
Esto debería manejar todos los caracteres (excepto las líneas nuevas) en un nombre de archivo.
¿Que está pasando aqui?
-
ls -t
enumera todos los archivos en el directorio actual en orden decreciente de tiempo de modificación. Es decir, los archivos modificados más recientemente son los primeros, un nombre de archivo por línea. -
sed -e ''1,10d''
borra las primeras 10 líneas, es decir, los 10 archivos más nuevos. Utilizo esto en lugar detail
porque nunca puedo recordar si necesitotail -n +10
otail -n +11
. -
xargs -d ''/n'' rm
recopila cada línea de entrada (sin la nueva línea de terminación) y pasa cada línea como argumento arm
.
Como con cualquier cosa de este tipo, por favor experimente en un lugar seguro.
Usar números de inodo a través del comando stat & find (para evitar problemas de molestos caracteres en el nombre de archivo):
stat -f "%m %i" * | sort -rn -k 1,1 | tail -n +11 | cut -d " " -f 2 | /
xargs -n 1 -I ''{}'' find "$(pwd)" -type f -inum ''{}'' -print
#stat -f "%m %i" * | sort -rn -k 1,1 | tail -n +11 | cut -d " " -f 2 | /
# xargs -n 1 -I ''{}'' find "$(pwd)" -type f -inum ''{}'' -delete
find
es la herramienta común para este tipo de tarea:
find ./my_dir -mtime +10 -type f -delete
EXPLICACIONES
-
./my_dir
su directorio (reemplace con el suyo) -
-mtime +10
más viejo que 10 días -
-type f
solo archivos -
-delete
ninguna sorpresa. Quítelo para probar su filtro defind
antes de ejecutar todo el comando
¡Y ./my_dir
que ./my_dir
exista para evitar malas sorpresas!
stat -c "%Y %n" * | sort -rn | head -n +10 | /
cut -d '' '' -f 1 --complement | xargs -d ''/n'' rm
Desglose: obtenga tiempos de última modificación para cada archivo (en el formato " filename
time
"), ordénelos del más antiguo al más reciente, conserve todas menos las últimas diez entradas y luego mantenga todo excepto el primer campo (conserve solo la parte del nombre del archivo) .
Editar : Usar cut
lugar de awk
ya que este último no siempre está disponible
Editar 2 : ahora maneja nombres de archivos con espacios