Trouvez les fichiers / répertoires les plus anciens dans le système de fichiers jusqu'à 50 To

8

J'ai besoin de trouver les fichiers les plus anciens avec leurs répertoires associés dans un système de fichiers de 90 To jusqu'à 50 To, puis de les déplacer vers un autre système de fichiers. Ils doivent conserver leur structure de répertoires car c'est ce qui identifie les fichiers. Donc -

premier niveau / deuxième niveau / troisième niveau / (fichier)

est la structure. J'ai besoin de déplacer toute cette structure - il n'y a rien dans les répertoires de niveau supérieur mais sans eux, je ne peux pas identifier à quoi appartient le fichier car tous les fichiers que je recherche ont le même nom. Une fois le processus terminé, il me reste environ 40 To dans le système de fichiers d'origine et presque rien dans le nouveau système de fichiers car les fichiers les plus anciens de l'original sont maintenant là.

Merci!

J Telep
la source

Réponses:

9

Avec les outils GNU et rsync, vous pourriez faire:

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/

(non testé. Le -nest pour un essai à sec. Retirez si heureux).

Notez que nous calculons la taille cumulée du fichier en fonction de la taille des fichiers ( %s, remplacez par %bpour l'utilisation du disque dans les secteurs (et passez à total_size += $2 * 512) et ignorez les liens durs. Ces fichiers, lorsqu'ils sont copiés dans le système de fichiers cible, avec les répertoires qui les contiennent finiront probablement par utiliser plus de 50 To (sauf s'il y a une compression ou une déduplication du système de fichiers en jeu).

Stéphane Chazelas
la source
1
Meilleure réponse que la mienne (bien que j'aurais ajouté un total_size > max { exit 0 }au script awk)
symcbean
@symcbean, bon point! Je l'ai ajouté maintenant. Merci.
Stéphane Chazelas
Cela a l'air génial !! Une question cependant - je suppose que la partie "max = 50e12" de l'instruction awk dicte au système que nous voulons 50 To, donc en fonction de dossiers supplémentaires (car il y en a deux pour chaque fichier) si je devais, je pourrais réduire que "50" à "49" et cela équivaudrait à 49 To?
J Telep
1
@JTelep, c'est de la notation scientifique. 50e12 est 50 fois 10 à la puissance de 12, donc 50 To (pas 50 To, dont vous auriez besoin 50 * 2^40). Vous pouvez également le modifier à l' total_size += $2 + overheadendroit où overheadest défini la surcharge générée par ces dossiers. Voir aussi %kau lieu de %spour obtenir l'utilisation du disque en Ko.
Stéphane Chazelas
2

La commande «ls» est quelque peu créative avec les horodatages - donc les analyser peut être pénible. Il serait probablement beaucoup plus facile d'implémenter cela dans un langage qui implémente stat (). Certaines versions d'Unix ont une statistique de ligne de commande - sur une boîte RH voisine:

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

Mais cela fonctionnera comme un chien avec un grand nombre de fichiers.

La documentation de GNU awk comprend un exemple d'extension fournissant des fonctions de système de fichiers, mais vous auriez besoin de faire un travail pour le construire et le maintenir.

Écrire un programme à partir de zéro en PHP, C ou Perl (ou go, ruby ​​ou de nombreux autres langages) serait simple mais au-delà de la portée d'un article ici.

symcbean
la source
1
Notez que GNU a statété ajouté longtemps après que GNU findait eu une -printfcommande (qui peut faire la même chose que GNU statavec une bien meilleure interface).
Stéphane Chazelas