|
Publicité ' | ||||||||||||||||||||||||
|
|
#1 |
|
Membre du Club
![]() Analyste/Développeur PHP/java Inscription : juillet 2007 Messages : 61 ![]() |
Bonjour
J'ai une liste de fichiers historisés sous la forme <nomfichier>-<aaaaMMjj-hhmm>.gz donc par exemple : titi-20110220_1400.gz toto-20110110_0900.gz titi-20110110_1000.gz toto-20110220_0700.gz Je veux pour chaque fichier (toto et titi) ne récupéré que le plus récents donc : toto-20110220_0700.gz titi-20110220_1400.gz car sinon je me retrouverai avec une liste qui pourrait en théorie atteindre pas loin de 1 million de fichiers... (en pratique ca tournerai plutôt aux alentour de 200 000 fichiers) mon but est d'avoir cette liste de fichiers (avec chemin depuis le dossier où le script se trouve) dans un tableau obligatoirement trié alphabétiquement donc pour le moment j'utilise find * | sort qui me retourne la liste des fichiers triée. Mon problème est de réussir à élaguer cette liste, j'ai vu que le find est très puissant, sauf que n'arrive pas à voir comment faire pour lui dire de ne prendre que la derniere historisation de chaque fichier... je connais la liste des fichiers (toto, titi) mais je ne veux pas avoir à faire une boucle pour recuperer chaque dernière occurence, car après l'algo va faire une boucle (c'est la raison pour laquelle je veux élaguer la liste avant de faire la boucle), l'algo n'ayant besoin que de la derniere historisation du fichier j'espère avoir été assez clair, au besoin demandez des précisions merci. |
|
01
|
|
|
#2 |
|
Expert Confirmé Sénior
![]() francois Ingénieur systèmes et réseaux Inscription : juillet 2006 Messages : 3 534 ![]() |
tu peux faire :
Code :
find /chemin/ -type f -name "*t[io]t[io]*" -mtime -90 |sort <options_selection> | tail -20 |
|
|
00
|
|
|
#3 |
|
Membre du Club
![]() Analyste/Développeur PHP/java Inscription : juillet 2007 Messages : 61 ![]() |
merci pour ton aide, mais ça ne peux pas marcher dans mon cas
déjà 1 : les fichiers je ne sais pas (quand j'écris le script) comment il s'appelleront... donc là j'ai donné titi et toto pour exemple, mais ca pourrait être apache-error-20110317_1206.gz ensuite tu met que le fichier a été modifier au cours des 90 derniers jours n'est ce pas ? donc déjà ce cas ne peux pas arriver, j'ai une purge qui est faite au maximum tous les 60jours ^^ (heureusement car vu le nombre de fichiers...) et ensuite là je ne veux pas les fichiers depuis n jours, mais pour chaque fichier de log ne récupéré sa dernière version historisée (cf exemple dans premier post).Donc je ne comprend pas non plus pourquoi tu fait un tail -20... plus précisément, j'ai dans mon dossier /tr_dac/ les logs "bruts" (récupéré depuis plusieurs dizaines de serveurs/applications) dans /tr_dah/ j'ai les version historisés (l'historisation se fait à plusieurs heures de la journée et/ou plusieurs jour de la semaine/mois, les serveurs/applis ont chacun leur configuration) mon but, est quand de vérifier si les log dans /tr_dac/ doivent être historisés ou non, pour le moment le script parcours la liste des fichiers de log brut (tr_dac) et fait un ls avec regex + tail -1 pour chaque fichier puis compare les date de derniere modif (entre le log brut et la derniere version historisée). le problème c'est que à chaque boucle ca fait une lecture disque... qui fait que que le processus prend énormément de temps, mon but est de passer par des tableaux, et donc de faire la lecture disque en un seul coup et non pas au coup par coup... |
|
01
|
|
|
#4 | ||
|
Expert Confirmé Sénior
![]() francois Ingénieur systèmes et réseaux Inscription : juillet 2006 Messages : 3 534 ![]() |
J'avais pas compris le besoin
pourquoi pas puisque tu horodates les fichier afficher tous les deniers fichiers par type? avec une boucle ? Code :
|
||
|
|
00
|
|
|
#5 |
|
Membre du Club
![]() Analyste/Développeur PHP/java Inscription : juillet 2007 Messages : 61 ![]() |
pas de problème, c'est pas facile à expliquer mon cas
non, ca va faire 10 000 ls comme c'est le cas aujourd'hui, et c'est ca que je veux changer et pour le FOR IN... comment je remplis les valeurs ? je ne les connais pas (et pi il peu y'en avoir plus de 10k ...) |
|
10
|
|
|
#6 |
|
Expert Confirmé Sénior
![]() francois Ingénieur systèmes et réseaux Inscription : juillet 2006 Messages : 3 534 ![]() |
non ça va afficher que "le dernier ls" de chaque
find aussi fait ça en réalité, dans son code, et tri les données en sortie en fonction des options.. la lecture de TOUS les fichiers par le programme que tu va lancer va forcément être faite. quel est le véritable rythme de création des fichiers ? si c'est moins d'une heure, il est préférable de changer de méthode et surtout de structure, ------------- AMHA la méthode est mauvaise de base, il faut : tu fais des répertoires par dates, qui contiennent des répertoires par heures, et un répertoire unique pour les 30 jours courants. que tu génères tes noms de fichiers par numérotation et pas par nom, ce qui résoud le problème du nom de fichier inconnu en le rendant prévisible et calculable. quand au problème de performance à la lecture d'une masse de fichier, gace à la découpe en répertoires : un script ou un crontab qui fait le rangement et du coup le temps d'analyse de la commande find sur les fichiers que des 30 derniers jours dans cette exemple et en cas d'echec, de chercher uniquement dans les 30 autres jours.. ainsi tu divises ton temps de réponse par 2 dans 50% des cas, à savoir le cas ou le fichier date de moins de 30 jours.. tu peux aussi aussi découper en 8 semaine temps / 8 dans 1/8 des cas temps / 2 dans 1/2 des cas temps == dans 1/8 des cas de ce que tu as aujourd'hui. --------------------- si c'est des fichiers qui se renouvellent : la méthode c'est le versionning --------------------- si c'est des datas, fait une recherche sur le contenu pas sur le contenant --------------------- |
|
|
00
|
|
|
#7 |
|
Membre du Club
![]() Analyste/Développeur PHP/java Inscription : juillet 2007 Messages : 61 ![]() |
je ne peux pas modifier l'arborescence pour le moment
d'autant plus que comment tu fais pour savoir s'il faut historiser ou non lefichier ? tu va aller voir dans la centaine de repertoire pour y trouver les version historisés ? car je n'historise à nouveau le fichier uniquement que s'il a été modifié (sinon pas d'interet à avoir 2 fois la même chose d'historisé ^^) et si je modifie le noms de mes fichiers, je ne saurais plus à quel fichier de base il correspondent... et pourquoi me parle tu de nom de fichier inconnu ??? quand je disais que je connaissait pas le nom, c'est dans le dossier "source" où se trouvent les fichiers à historiser... les nom des fichiers historisés "je" les connais car il ont le nom du fichier "source" + la date pour le rythme, c'est totalement aléatoire... il peut y avoir des nouveaux fichiers toutes les heures comme il peut y'en avoir qu'une fois par semaine... de plus le ls ne retourne pas le path du fichier, or j'en ai absolument besoin... |
|
10
|
|
|
#8 |
|
Membre éclairé
![]() Inscription : février 2011 Messages : 83 ![]() |
Il n'y a qu'un répertoire source ? Quel est la forme des fichiers sources ? titi.gz toto.gz ? (extension ? ou pas ?).
Si non, donne un exemple de structure des répertoires sources / format de fichiers, etc... s'il te plait. |
|
|
10
|
|
|
#9 | ||
|
Expert Confirmé Sénior
![]() Inscription : février 2008 Messages : 2 070 ![]() |
Bonjour,
Code bash4 :
? |
||
|
|
10
|
|
|
#10 |
|
Membre du Club
![]() Analyste/Développeur PHP/java Inscription : juillet 2007 Messages : 61 ![]() |
Bonjour
@n_bah pourrais tu expliquer ton code car j'y comprends pas grand chose là... @fruit il y'a une arborescence de répertoire sources qui sont tous dans /sources/appli1/ donc on pourrait avoir ca par exemple : /sources/appli1/toto.txt /sources/appli1/dossier1/tata.log /sources/appli1/dossier1/sousdossier11/sousdossier111/pouet.camembert /sources/appli1/dossier2/sousdossier21/tagazok.log etc... les fichiers viennent de d'autres serveurs/applications qui sont eux/elles même différentes... (log apache, de bases de données, logs applicatifs)/(linux, windows server, solaris...) les fichiers sources sont compressés, ils ont donc tous l'extension .gz (qui est rajouté en fait au nom du fichier brut, par exemple titi.txt devient titi.txt.gz) et moi je veux avoir des fichiers historisés sous la forme titi.txt-20110318_1130.gz |
|
10
|
|
|
#11 | ||
|
Expert Confirmé
![]() Inscription : janvier 2011 Messages : 970 ![]() |
Salut,
Est-ce que tes fichiers auront toujours le même format (nom tiret date underscore nombre point extension) ? Si oui (et qu'un seul tiret dans le nom), en trifouillant "sort" voila ce que ça peut donner : Code :
__________________
$ man woman Il n'y a pas de page de manuel pour woman. |
||
|
|
10
|
|
|
#12 |
|
Membre du Club
![]() Analyste/Développeur PHP/java Inscription : juillet 2007 Messages : 61 ![]() |
non, en fait déjà en réalité c'est pas un tiret mais un point qui est utilisé pour séparer le nom du fichier de la date, mais de toute manière, je peux avoir des points et tirets dans le nom des fichiers... j'ai même du faire en sorte que les caractère $ (){}[] et ' soient supportés
de plus ta solution n'est pas utilisation car tu utilises la commande ls qui ne retourne pas le chemin du fichier alors que je le veux impérativement |
|
10
|
|
|
#13 | |
|
Expert Confirmé Sénior
![]() francois Ingénieur systèmes et réseaux Inscription : juillet 2006 Messages : 3 534 ![]() |
Citation:
tu pourrais faire un find redirigé vers un fichier utiliser Code :
sort -r -t '_' +1 -0.8 | sort -t '-' -u -k 1,1 ce qui te rend l'utilisation possible : ${chemin}${fichier} pour reconstituer /home/fromage/qui/puent/camember-2.0 |
|
|
|
00
|
|
|
#14 |
|
Membre du Club
![]() Analyste/Développeur PHP/java Inscription : juillet 2007 Messages : 61 ![]() |
tu pourrait explique ton double sort stp, je n'arrive pas à comrpendre l'utilité (ni tous les paramètres que tu utilises et pourquoi tu les utilises...)
(pour info, bon déjà avec mon nouvel algo je passe de 4h à 45min de traitement ^^, mais si je pouvais encore diminuer plus avec ce que je vous demande ici, ca serait parfait ^^) |
|
10
|
|
|
#15 |
|
Expert Confirmé
![]() Inscription : janvier 2011 Messages : 970 ![]() |
-r
Tri inversé -t '_' On choisis l'underscore ( _ ) comme séparateur de champs +1 On trie à partir du second champs (pour rappel, la numérotation des champs commence à "0" (zéro)) -0.8 Le tri se fera sur 8 positions, mais comme il est précédé par un signe négatif, on triera sur 8 positions mais sur le champ précédent en partant de la fin, donc sur la date. -t '-' On choisis le tiret ( - ) comme séparateur de champs -u On affichera qu'un résultat unique pour chaque concordance -k 1,1 Concordance qui se fera sur le 1er champ (ici avec -k qui lui numérote à partir de 1)
__________________
$ man woman Il n'y a pas de page de manuel pour woman. |
|
|
10
|
|
|
#16 |
|
Membre du Club
![]() Analyste/Développeur PHP/java Inscription : juillet 2007 Messages : 61 ![]() |
ok merci, ca à l'air de marcher, mais j'ai du mal à comprendre pourquoi...
voilà ce que j'ai compris : le sort -r -t '_' +1 -0.8 permet de trier à l'envers, sur le <nomfichier>-date à condition que je n'ai pas plus de 8 _ dans le nom du fichier c'est ca ? j'ai du mal à voir la différence entre le +1 et le -0.8 ... donc on aurait : titi-20110110_1000.gz toto-20110220_0700.gz toto-20110228_0030.gz titi-20110220_1400.gz toto-20110110_0900.gz titi-20110215_2300.gz qui serait trié ainsi : toto-20110228_0030.gz toto-20110220_0700.gz toto-20110110_0900.gz titi-20110220_1400.gz titi-20110215_2300.gz titi-20110110_1000.gz le deuxième sort, ne permet de récupérer que le nom du fichier non ? en triant sur le nom du fichier et comme il y'a le -u ca ne retourne que le premier résultat, soit dans notre cas le plus récent car la liste est inversée (sinon ca retournerai le plus vieux). Questions : le -u retourne il obligatoirement le premier de la liste ? le premier sort utilise la date, mais si pour une meme date j'ai deux fichiers : avec juste l'heure qui différe titi-20110215_2300.gz titi-20110215_1000.gz comment ca se passe dans ce cas ? sinon, dans la réalité le fichier est plutot : titi.txt.20110110_1000.gz ne serait il pas plutôt judicieux de faire pour le premier sort : sort -r -t '.' -1 pour dire de trier sur des champs séparé par des . et en prenant le 2eme en partant de la fin ? car c'est ce qui correspond à : 20110110_1000 ? |
|
10
|
|
|
#17 | |||||||||
|
Expert Confirmé
![]() Inscription : janvier 2011 Messages : 970 ![]() |
Citation:
![]() Citation:
Ici on utilise un clé de tri, le fameux "+1 -0.8" qui signifie qu'on va trier sur le champ 2 (+1 vu qu'on démarre de zéro). Donc : champ 1 (0) = titi-20110110 champ 2 (1) = 1000.gz Mais comme on a spécifié une position (-0.8), négative de surcroit, le tri se fera sur les 8 caractères précédents, donc la date (20110110). Ensuite comme spécifié dans le "man sort" : Finalement, si toutes les clés sont égales, en dernier ressort sort compare les lignes octet par octet suivant l'ordre défini sur la machine. Citation:
-0.8 c'est les 8 caractères précédent le champ 2 Le critère de tri se fera sur cette zone. Citation:
Citation:
Code :
Citation:
Citation:
Par contre pour le second sort, oui il faut effectivement changer le "-t '-'" par "-t '.'", et peut être étendre le critère au second champ... mais ça c'est en fonction de tes besoins.
__________________
$ man woman Il n'y a pas de page de manuel pour woman. |
|||||||||
|
|
20
|
|
|
#18 |
|
Membre du Club
![]() Analyste/Développeur PHP/java Inscription : juillet 2007 Messages : 61 ![]() |
et si jamais j'ai par exemple ce nom de fichier :
ti_to.re_t.a.e.r.a_pe_pu_pi.20100321_0900.gz ? est ce que ca fonctionnera aussi ? |
|
01
|
|
|
#19 |
|
Expert Confirmé
![]() Inscription : janvier 2011 Messages : 970 ![]() |
Non, c'est ce que je t'ai expliqué plus haut
__________________
$ man woman Il n'y a pas de page de manuel pour woman. |
|
|
10
|
|
|
#20 |
|
Membre du Club
![]() Analyste/Développeur PHP/java Inscription : juillet 2007 Messages : 61 ![]() |
ok c'est bien ce qu'il me semblait (désolé, c'est lundi matin, j'ai le cerveau encore engourdi...)
une solution pour corriger ce problème qui est très gênant pour moi ? |
|
01
|
Copyright © 2000-2012 - www.developpez.com