otro - Comando Bash para eliminar todos los directorios menos 5 Ășltimos
eliminar directorio linux sin confirmacion (5)
Posible duplicado:
Borra todos los archivos X menos los más recientes en bash
Tengo un script para crear copias de seguridad incrementales diariamente y necesito eliminar todas las copias de seguridad, pero las 5 últimas.
Por ejemplo, tengo estas carpetas:
drwxr-xr-x 4 root root 4096 Oct 29 01:10 2010-10-29 drwxr-xr-x 4 root root 4096 Oct 30 01:10 2010-10-30 drwxr-xr-x 4 root root 4096 Oct 31 01:10 2010-10-31 drwxr-xr-x 4 root root 4096 Nov 1 01:10 2010-11-01 drwxr-xr-x 4 root root 4096 Nov 2 01:10 2010-11-02 drwxr-xr-x 4 root root 4096 Nov 3 01:10 2010-11-03 drwxr-xr-x 4 root root 4096 Nov 4 01:10 2010-11-04 drwxr-xr-x 4 root root 4096 Nov 5 01:10 2010-11-05 drwxr-xr-x 4 root root 4096 Nov 6 01:10 2010-11-06 drwxr-xr-x 4 root root 4096 Nov 7 01:10 2010-11-07 drwxr-xr-x 4 root root 4096 Nov 8 01:10 2010-11-08
Y necesito mantener solo los últimos 5 directorios y eliminar los otros. Después de ejecutar el comando, necesito tener solo esto:
drwxr-xr-x 4 root root 4096 Nov 4 01:10 2010-11-04 drwxr-xr-x 4 root root 4096 Nov 5 01:10 2010-11-05 drwxr-xr-x 4 root root 4096 Nov 6 01:10 2010-11-06 drwxr-xr-x 4 root root 4096 Nov 7 01:10 2010-11-07 drwxr-xr-x 4 root root 4096 Nov 8 01:10 2010-11-08
No necesito eliminar los últimos 5 días, necesito eliminar todos los directorios excepto 5 últimos :)
Ahora estoy usando:
find /backup/increment -maxdepth 1 -type d -mtime +5 -exec rm -rf {} /;
Pero necesito mejorar no basándome en el tiempo :)
EDITAR: Este es un ejemplo para un servidor que realiza copias de seguridad todos los días, pero necesito una secuencia de comandos que elimine todas las carpetas anteriores a las últimas 5 porque mi computadora hace copias de seguridad a las 00:10 de la noche, pero no todas las noches que se realiza la copia de seguridad, porque mi computadora no funciona todos los días, y necesito tener siempre las últimas 5 copias de seguridad :)
Crea dos archivos ficticios con el inicio y la fecha de finalización.
touch -t 1010290000 before
touch -t 2011042359 after
encuentre todos los archivos entre los 2 archivos ficticios y "rm -rf" el resultado
find . -newer before /! -newer after -exec rm -rf {} /;
El truco será la opción -t a ls, que se ordena por hora de modificación, de la más reciente a la más antigua.
Una solución realmente ingenua, usando un archivo temporal, podría ir de esta manera:
ls -t > /tmp/file_list
num_files_to_keep=5
# wc -l gets the line count of a file
# first word of wc output is the actual line count, and that''s all we need, so
# delete everything after the space.
num_files=`wc -l /tmp/file_list | sed "s/ .*//"`
#if appropriate you should add a check for num_files < num_files_to_keep
num_files_to_delete=$(( $num_files - $num_files_to_keep ))
rm `tail -n $num_files_to_delete /tmp/file_list`
Lo primero que me vino a la mente. No es elegante
a=0;
for i in `ls -t`;
do
a=`expr $a + 1`;
if [ $a -gt 5 ]; then
echo "removing $i";
rm -rf $i
fi;
done
ls -tr | perl -ne ''{@files = <>; imprimir archivos @ [0 .. $ # archivos-5]} ''| xargs -n1 echo rm -rf
Debería eliminar el eco antes de rm -rf para que funcione.
use el comando tail
para imprimir líneas comenzando con la línea n (Opción -n +N
):
rm `ls -t | tail -n +6`
ls -t
genera el directorio actual ordenado por tiempo. tail -n +6
toma todas las líneas comenzando con la 6ª línea. La cotización con backticks alimenta el resultado de la tubería en el comando rm
.
SOLUCIÓN ANTIGUA, no correcta ...
use el comando head
, que imprime las primeras n líneas de alguna salida:
rm `ls -t1 | head -n 5`
ls -t
genera el directorio actual ordenado por tiempo. head -n 5
toma las primeras cinco entradas de la salida anterior. La cotización con backticks alimenta el resultado de la tubería en el comando rm
.
Por favor, intente primero antes de aplicar a los datos en vivo :) ...