Tengo varios archivos de registro con el formato:
log.2014-02-19-10_24_22
Es decir. registro.AAAA-MM-DD-H24_MI_SS
La fecha que forma parte del nombre del archivo de registro es cuando se creó por primera vez. Entonces, en cualquier momento, puedo tener los siguientes archivos de registro en mi directorio:
log.2014-02-19-10_18_54
log.2014-02-19-10_21_20
log.2014-02-19-10_23_11
etc.
Ahora tengo un script que es invocado por un cronjob y que elimina los archivos de registro "antiguos":
$ cat delete-old-rotated-logs
#!/usr/bin/env bash
find /home/foo -maxdepth 1 -iname log* -type f -mmin +1800 -exec rm {} ;
El problema al que me enfrento es que, a veces, el proceso que está registrando se bloquea, por lo que el archivo de registro "más reciente" también se vuelve "antiguo" después de un tiempo (ya que no hay ningún proceso escrito en él) y se elimina, lo que me hace perder el rastro. ¿Cómo puedo volver a escribir delete-old-rotated-logs
? script para que elimine archivos antiguos excepto el último (o el último N
) ? Para el pedido, se puede usar tanto el nombre del archivo como la marca de tiempo de modificación (más robusta).
Respuesta aceptada:
find /home/foo -maxdepth 1 -iname log* -type f -mmin +1800 |
sort | head -n -1 | xargs rm
O si quieres usar mtime
en lugar del nombre de archivo:
find /home/foo -maxdepth 1 -iname log* -type f -mmin +1800 -exec ls -t {} + |
tail -n +2 | xargs rm
De los comentarios de @Stephane, un enfoque más sólido sería hacer:
IFS=$'n'
set -f
rm $(
find /home/foo -maxdepth 1 -iname log* ! -name $'*n*' -type f -mmin +1800 |
sort | head -n -1 )
O para shell POSIX (todavía requiere herramientas GNU):
IFS='
'
ex_newline='*
*'
set -f
rm $(
find /home/foo -maxdepth 1 -iname log* ! -name "$ex_newline" -type f -mmin +1800 |
sort | head -n -1 )
Se puede usar una canalización única (robusta) con una versión reciente de GNU sed
/sort
(y GNU encuentra como con todo lo anterior):
find /home/foo -maxdepth 1 -iname log* -type f -mmin +1800 -print0 |
sort -z | sed -z '$d' | xargs -0 rm