Encuentra los archivos / directorios más antiguos en el sistema de archivos de hasta 50 TB

8

Necesito encontrar los archivos más antiguos con sus directorios asociados en un sistema de archivos de 90 TB hasta 50 TB y luego moverlos a otro sistema de archivos. Tienen que conservar su estructura de directorios, ya que eso es lo que identifica los archivos. Entonces -

primer nivel / segundo nivel / tercer nivel / (archivo)

Es la estructura. Necesito mover toda esa estructura; no hay nada en los directorios de nivel superior, pero sin ellos no puedo identificar a qué pertenece el archivo, ya que todos los archivos que estoy buscando tienen el mismo nombre. Cuando se complete el proceso, debería tener aproximadamente 40 TB en el sistema de archivos original y casi nada en el nuevo sistema de archivos, ya que los archivos más antiguos en el original ahora están allí.

¡Gracias!

J Telep
fuente

Respuestas:

9

Con las herramientas GNU y rsync, podría hacer:

export LC_ALL=C # force tools to regard those file paths as arrays
                # of bytes (as they are in effect) and not do fancy
                # sorting (and use English for error/warning messages 
                # as an undesired side effect).

find . -type f -printf '%T@/%s/%p\0' | # print mtime/size/path
  sort -zn | # numerical sort, oldest first
  awk -v RS='\0' -v ORS='\0' -F / -v max=50e12 '
    {total_size += $2}
    total_size > max {exit}
    {
      sub("^[^/]*/[^/]*/", "") # remove mtime/size/
      print # path
    }' |
  rsync -nv -aHAX0 --files-from=- --remove-source-files . /dest/dir/

(no probado. -nEs para funcionamiento en seco. Eliminar si está satisfecho).

Tenga en cuenta que estamos calculando el tamaño de archivo acumulativo en función de los tamaños de archivo ( %s, reemplace %bpor el uso del disco en sectores (y cambie a total_size += $2 * 512) e ignorando los enlaces duros. Esos archivos, cuando se copian al sistema de archivos de destino, junto con los directorios que los contengan probablemente terminará usando más de 50 TB (a menos que haya compresión del sistema de archivos o deduplicación en juego).

Stéphane Chazelas
fuente
1
Mejor respuesta respuesta que la mía (aunque habría agregado una total_size > max { exit 0 }al script awk)
symcbean
@symcbean, buen punto! Lo he agregado ahora. Gracias.
Stéphane Chazelas
¡Esto se ve genial! Sin embargo, una pregunta: estoy asumiendo que la porción "max = 50e12" de la declaración awk está dictando al sistema que queremos 50 TB, por lo que en función de las carpetas adicionales (ya que hay dos para cada archivo), si fuera necesario, podría reducir que "50" a "49" y eso equivaldría a 49 TB?
J Telep
1
@JTelep, eso es notación científica. 50e12 es 50 veces 10 a la potencia de 12, entonces 50TB (no 50TiB, para lo que necesitarías 50 * 2^40). También puede cambiarlo a total_size += $2 + overheaddonde overheadse define como la sobrecarga incurrida por esas carpetas. Consulte también en %klugar de %sobtener el uso del disco en KiB.
Stéphane Chazelas
2

El comando 'ls' es algo creativo con marcas de tiempo, por lo que analizarlas puede ser una molestia. Probablemente sería mucho más fácil implementar esto en un lenguaje que implemente stat (). Algunas versiones de Unix tienen una estadística de línea de comando , en un cuadro RH cercano:

 find ${BASEDIR} -type f -exec stat --format="%y %b %n" {} \; | sort | less

Pero esto se ejecutará como un perro con una gran cantidad de archivos.

La documentación para GNU awk incluye una extensión de ejemplo que proporciona funciones del sistema de archivos, pero necesitaría hacer un trabajo para construir y mantener esto.

Escribir un programa desde cero en PHP, C o Perl (o go, ruby ​​u muchos otros lenguajes) sería sencillo pero más allá del alcance de una publicación aquí.

symcbean
fuente
1
Tenga en cuenta que GNU statse agregó mucho después de que GNU findtuviera un -printfcomando (que puede hacer lo mismo que GNU statcon una interfaz mucho mejor).
Stéphane Chazelas