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
3 Réponses :
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
Merci - je suis d'accord avec ça
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.
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 $_; }
@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