Cómo eliminar archivos de más de X horas

191

Estoy escribiendo un script bash que necesita eliminar archivos antiguos.

Actualmente se implementa usando:

find $LOCATION -name $REQUIRED_FILES -type f -mtime +1 -delete

Esto eliminará los archivos anteriores a 1 día.

Sin embargo, ¿qué pasa si necesito una resolución más fina que 1 día, digamos como 6 horas? ¿Hay una manera agradable y limpia de hacerlo, como si se usa find y -mtime?

Tom Feiner
fuente

Respuestas:

303

¿ findTienes la -mminopción? Eso puede permitirle probar la cantidad de minutos desde la última modificación:

find $LOCATION -name $REQUIRED_FILES -type f -mmin +360 -delete

O tal vez mira usar tmpwatchpara hacer el mismo trabajo. phjr también recomendado tmpreaperen los comentarios.

Paul Dixon
fuente
2
El uso de --mmin + X devuelve todos los archivos con mi búsqueda. Es mi culpa por no comprobar esto primero, pero este comando acaba de eliminar la mayor parte de mi directorio personal. Para mí, --mmin -X es el argumento correcto.
Brandones
tmpreaper es un tenedor de tmpwatch. Es más seguro y existe como un paquete debian en la distribución. Beneficios sobre find -delete: tmpreaper no eliminará enlaces simbólicos, sockets, fifos o archivos especiales
Nadir
Señale que $ REQUIRED_FILES debe estar entre comillas (comillas dobles) y puede usar un patrón como: " .txt" para todos los archivos .txt o archivos que comienzan con un patrón como: "temp- " para eliminar todos los archivos nombrados con temp -
achasinh
@PaulDixon cómo modificar esto para que $LOCATIONy $REQUIRED_FILESambos pueden tener múltiples valores como dir1 dir2e *.txt *.tmp?
Enissay
@Enissay $ LOCATION es un directorio único. Para múltiples extensiones, es probable que desee utilizar un patrón con -regex - consulte stackoverflow.com/questions/5249779/…
Paul Dixon el
9

Podrías hacer este truco: crear un archivo hace 1 hora y usar el -newer fileargumento.

(O úselo touch -tpara crear dicho archivo).

xtofl
fuente
1
no hay un interruptor más antiguo (al menos en mi comando de búsqueda), y eso es lo que se necesitaría. -Nuevo no ayuda.
iconoclasta
¿Puedes dar un comando táctil que generaría un archivo de 1 hora de antigüedad que funcionará en máquinas que no pueden usar -mmin? (Si estás en Linux, -mmin está disponible, si no, la fecha y otros comandos también son débiles en comparación.)
iconoclasta
2
@iconoclast touch -t $(date -d '-1 hour' +%Y%m%d%H%M.00) testCrea un archivo testque siempre tiene 1 hora de antigüedad.
rovr138
4

Aquí está el enfoque que funcionó para mí (y no veo que se use anteriormente)

$ find /path/to/the/folder -name *.* -mmin +59 -delete > /dev/null

eliminar todos los archivos anteriores a 59 minutos y dejar las carpetas intactas.

Axel Ronsin
fuente
Es mejor comillas simples '*.*'o el shell lo expandirá a nombres de archivo reales en lugar de mantenerlo como un comodín para findresolver. Esto interrumpe findla operación recursiva en subdirecciones.
MestreLion
También hay que tener en cuenta que -name '*.*'no va a borrar archivos que no tienen una extensión, tales como README, Makefile, etc.
MestreLion
1

Para SunOS 5.10

 Example 6 Selecting a File Using 24-hour Mode


 The descriptions of -atime, -ctime, and -mtime use the  ter-
 minology n ``24-hour periods''. For example, a file accessed
 at 23:59 is selected by:


   example% find . -atime -1 -print




 at 00:01 the next day (less than 24 hours  later,  not  more
 than one day ago). The midnight boundary between days has no
 effect on the 24-hour calculation.
Rajeev Rumale
fuente
0

-mmin es por minutos.

Intenta mirar la página del manual.

man find

para más tipos

GavinCattell
fuente
0

Si no tiene "-mmin" en su versión de "find", entonces "-mtime -0.041667" se acerca bastante a "en la última hora", por lo tanto, en su caso, use:

-mtime +(X * 0.041667)

entonces, si X significa 6 horas, entonces:

find . -mtime +0.25 -ls

funciona porque 24 horas * 0.25 = 6 horas

Malcolm Boekhoff
fuente
Tenía esperanzas porque este antiguo UNIX no tiene -mmin, pero, lamentablemente, esto no ayuda, ya que este antiguo UNIX tampoco le gustan los valores fraccionales para mtime: find: el argumento to -mtime debe ser un número entero en el rango -2147483647 a 2147483647
kbulgrien
0

Esto es lo que se puede hacer para seguir el camino que @iconoclast se preguntaba en su comentario sobre otra respuesta.

use crontab para el usuario o an /etc/crontabpara crear el archivo /tmp/hour:

# m h dom mon dow user  command
0 * * * * root /usr/bin/touch /tmp/hour > /dev/null 2>&1

y luego usa esto para ejecutar tu comando:

find /tmp/ -daystart -maxdepth 1 -not -newer /tmp/hour -type f -name "for_one_hour_files*" -exec do_something {} \;
satyr0909
fuente
*/1por hora es redundante en su crontab. Es lo mismo que poner * en el campo de la hora.
colm.anseo
0

find $PATH -name $log_prefix"*"$log_ext -mmin +$num_mins -exec rm -f {} \;

Eragonz91
fuente
0

Si uno findno tiene -mminy si uno también está atascado con un findque acepta solo valores enteros para -mtime, entonces no todo se pierde necesariamente si uno considera que "más antiguo que" es similar a "no más nuevo que".

Si pudiéramos crear un archivo que tiene un tiempo m de nuestro tiempo de corte, podemos solicitar findlocalizar los archivos que "no son más nuevos que" nuestro archivo de referencia.

Para crear un archivo que tiene la marca de hora correcta es un poco involucrados debido a que un sistema que no tenga una adecuada findprobablemente también tiene una menor a la capacidad datede comando que podría hacer cosas como: date +%Y%m%d%H%M%S -d "6 hours ago".

Afortunadamente, otras herramientas antiguas que pueden manejar esto, aunque de una manera más difícil de manejar.

Considere que seis horas son 21600 segundos. Queremos encontrar el tiempo que hace seis horas en un formato que sea útil:

$ date && perl -e '@d=localtime time()-21600; \
  printf "%4d%02d%02d%02d%02d.%02d\n", $d[5]+1900,$d[4]+1,$d[3],$d[2],$d[1],$d[0]'
> Thu Apr 16 04:50:57 CDT 2020
202004152250.57

La declaración perl produjo una fecha útil, pero debe utilizarse mejor:

$ date && touch -t `perl -e '@d=localtime time()-21600; \
  printf "%4d%02d%02d%02d%02d.%02d\n", \
  $d[5]+1900,$d[4]+1,$d[3],$d[2],$d[1],$d[0]'` ref_file && ls -l ref_file
Thu Apr 16 04:53:54 CDT 2020
-rw-rw-rw-   1 root     sys            0 Apr 15 22:53 ref_file

Ahora la solución para este antiguo UNIX es algo similar a:

$ find . -type f ! -newer ref_file -a ! -name ref_file -exec rm -f "{}" \;

También podría ser una buena idea limpiar nuestro archivo de referencia ...

$ rm -f ref_file
kbulgrien
fuente