2
votes

Comment trouver d'anciens fichiers volumineux et générer des métriques pour les répertoires contenant ces fichiers

Je suis un ingénieur matériel travaillant dans un département de conception et nous générons régulièrement des répertoires avec de grandes quantités de données (à la fois de gros fichiers et des répertoires contenant un grand nombre de petits fichiers). Ces données peuvent rester sur le disque pendant un certain temps et je recherche une métrique pour identifier les répertoires contenant de grandes quantités de données anciennes comme candidats à la suppression.

La métrique que j'ai choisie est la taille du fichier (en M ) * Âge du fichier (en jours).

J'ai une solution qui fonctionne, mais c'est une combinaison de scripts shell et de c et n'est ni maintenable, ni jolie ni élégante.

Je suis à la recherche d'idées pour améliorer le script.

L'idée de base est de générer des données brutes sur tous les fichiers en utilisant find

for Directory in $( find /projects/solaris/implementation -maxdepth 4 -type d ) ; do
  Total=`grep $Directory/ rpt3a | sed -e 's?,.*??' | paste -sd+ - | bc`
  echo $Total,$Directory >> rpt3c
done

puis de traiter ce fichier dans C pour obtenir un fichier (rpt3b) au format

Métrique, Âge, Taille, Nom du fichier

La métrique est l'âge * la taille

L'âge est le nombre de jours depuis le fichier a été modifié

La taille est la taille du fichier en M

FileName est le nom du fichier.

Je traite ensuite ce fichier pour additionner les métriques pour chaque répertoire

find $Dir -type f -exec stat -c "%s,%Y,%n" {} \; > rpt3

La sortie est donc similaire à un du, mais c'est la métrique qui est rapportée plutôt que la taille prise sur le disque.

Je pourrais extraire le dernière étape dans le programme C, mais je recherche une solution qui fonctionne idéalement dans un environnement (ne doit pas être C, je suis ouvert à l'apprentissage de nouvelles langues).

Merci d'avance


0 commentaires

3 Réponses :


0
votes

Utilisez cut pour extraire la colonne correcte de vos lignes extraites à la place de sed . cut -d, -f3 extraira la troisième colonne séparée par , .

Avec entrée:

15

commande grep a / a.txt | couper -f3 -d, | coller -sd + - | bc produira:

20

et la commande grep b / a.txt | couper -f3 -d, | coller -sd + - | bc :

10,2,5,a/b
20,4,5,a/c
30,2,15,b/d
40,4,10,a/d


1 commentaires

Merci - je suis d'accord avec ça



0
votes

Appelez 'python script.py startdir ~ / somefile.txt' .

Vous pouvez l'utiliser comme point de départ:

0.0,0.0,0.0011606216430664062,./main.py
0.0,0.0,0.0,./myfiles.txt
0.0,total,dictionary,./

Exemple de fichier - (sans coupure - en utilisant https://pyfiddle.io/ ):

import os
import sys
import time

def get_age_in_days(file_stats):
    """Calculate age in days from files stat."""
    return (time.time() - file_stats.st_mtime) // (60*60*24) 

def get_size_in_MB(file_stats):
    """Calculate file size in megabytes from files stat."""
    return file_stats.st_size / (1024 * 1024)

def metric(root,f):
    """Uses root and f to create a metric for the file at 'os.path.join(root,f)'"""
    fn = os.path.join(root,f)
    fn_stat = os.stat(fn) 
    age = get_age_in_days(fn_stat)
    size = get_size_in_MB(fn_stat)
    metric = age*size

    return [metric, age, size, fn] 

path = None
fn   = None
if len(sys.argv)==3:
    path = sys.argv[1]
    fn = sys.argv[2]
else:
    sys.exit(2)


with open(fn,"w") as output:  
    # walk directory recursivly and report anything with a metric > 1 
    for root,dirs,files in os.walk(path):
        total_dict = 0
        for f in files:
            m = metric(root,f)

            # cutoff - only write to file if metric > 1
            if m[0] > 1: 
                total_dict += m[0]
                output.write(','.join(map(str,m))+"\n")
       output.write(','.join([str(total_dict), "total","dictionary",root])+"\n")

# testing purposes
# print(open(fn).read())

Vous pouvez rechercher n'importe quelle ligne contenant , total, dictionnaire, : 0.0, total, dictionary,. / pour les totaux du dictionnaire.


0 commentaires

4
votes

Vous pouvez tout faire en Perl. Perl est livré avec deux opérateurs -M et -s qui sont respectivement l'âge du fichier en jours et la taille du fichier en octets. L'âge est ici l'heure de début du script moins l'heure de modification du fichier, ainsi que le module File :: Find qui imite la commande find.

#!perl
use strict;
use warnings;

use File::Find;

find(\&process, shift); # shift the start directory off @ARGV

sub process {
    # Lots of use of the magic _ file handle so we don't keep having to call stat()
    print( (-M _) * (-s _), ' ', -M _, ' ', -s _, " $File::Find::name\n")
        if -f $_;
}


4 commentaires

@zdim Cela devrait fonctionner. maintenant. Cela a fonctionné lorsque je l'ai testé la dernière fois car mon répertoire initial était ..


Merci :) (Je voudrais aussi arrondir les nombres et trier par métrique)


@zdim Je vais laisser cela comme un exercice pour l'affiche, ils voudront peut-être le faire par options :-)


Merci beaucoup pour votre aide. Était assez pour me faire avancer