Page 1 sur 1

[R] Nettoyer log

Posté : jeu. 26 août 2010 23:36
par ricky
Hello,

voilà, j'ai un nouveau problème...

J'ai des fichiers logs qui font entre 10 et 40 Mo, donc je vous laisse imaginer le nombre de lignes qu'il y a dedans...
Dans ces fichiers, beaucoup de lignes sont inutiles, pour cela il faudrait que je puisse lancer ligne par ligne une fonction qui recherche une combinaison de caractères et selon ce qu'il trouve fasse une opération...

Voici ce que je cherche :
  • Lecture ligne par ligne
  • Suppression de la ligne en lecture et/ou la précédente
  • Recherche de mot clé et selon prise des prochains caractères jusqu'au prochain espace *
* exemple : RecordID:1234567890 test-salut
En rouge, le mot clé et en orange la valeur à extraire et envoyer dans une variable

J'ai vu cette udf : ici et dans l'aide, mais je n'ai rien vu d'intéressant...

Merci d'avance pour votre aide.

Re: [..]Nettoyer log

Posté : ven. 27 août 2010 08:45
par SrBelial
lecture ligne par ligne :
* filereadline()

recherche de mot clé :
* StringInStr()
* éventuellement StringLeft() si tes mots clés ont une taille définie, puis un StringCompare()

récupérer les caractères suivants :
* tu as trouvé le mot clé : fais un StringReplace() pour l'enlever de la ligne lue,
RecordID:1234567890 test-salut => 1234567890 test-salut
* ensuite StringSplit() pour séparer les mots (délimiter = ' ' espace)
1234567890 test-salut => $resultat[1] = 1234567890 $resultat[2] = test-salut

voila voila ... en somme rien de bien sorcier,
sinon pour l'udf ça sera peut être "légèrement" plus simple à utiliser ... encore que .... ^___^

Re: [..]Nettoyer log

Posté : ven. 27 août 2010 08:56
par ricky
Ok, mais est-il possible de connaître à l'avance le nombre de lignes que comporte le fichier?

Comment supprimer une ligne?

Re: [..]Nettoyer log

Posté : ven. 27 août 2010 12:23
par SrBelial
il me semble qu'il existe une fonction permettant de connaitre le nombre de lignes ... je ne saurai en dire plus, si quelqu'un le sait ... ^__^
pour ce qui est de supprimer une ligne, le plus simple est de reconstruire un autre log, ligne à ligne, en ne recopiant que celles que tu souhaite garder ....
si ton log est vraiment gros ça sera la solution la plus rapide, tout simplement car parcourir un fichier en lecture et écrire un autre en parallèle conserve à coup sur une complexité linéaire (complexité égale au nombre de lignes du fichier) alors que n'importe quelle autre solution ou il te faudrait réécrire dans le log d'origine imposerait de façon implicite en quelque sorte de réécrire à chaque fois toutes les lignes qui restent après la ligne courante ... parce que supprimer une ligne on sait faire, mais en vrai dans le fichier lui même il va pas garder la place qu'il utilisait pour stocker la ligne supprimée, ça veut dire qu'a chaque enregistrement il doit décaler toutes les données placées après cette ligne pour qu'elles viennent remplir le vide ...

je sais pas si c'est très clair .... ^__^

Re: [..]Nettoyer log

Posté : ven. 27 août 2010 12:55
par jbnh
Pour le nombre de ligne

Code : Tout sélectionner

#include <file.au3>

_FileReadToArray($filename, $array)
For $X = 1 to $Array[0]    
       $var = FileReadLine($filename, $X)    
    EndIf
Next
ou array[0] est le nombre

Re: [..]Nettoyer log

Posté : ven. 27 août 2010 13:08
par ricky
Justement, c'est ce que j'avais dans l'idée, il supprime la ligne et va mettre à jour le nombre total de lignes. Mais je vais voir pour cette histoire d'en recrée un nouveau...

J'ai trouvé un début de solution pour compter les lignes, un filereadline qui sert à rien avec un += 1 dans une variable qui se trouve dans cette boucle.

Code : Tout sélectionner

While 1
        FileReadLine($fileIn)
        If @error = -1 Then ExitLoop
        $lines += 1
    Wend
Edit : jbnh nos messages se sont croisés

Re: [..]Nettoyer log

Posté : sam. 28 août 2010 10:49
par moutelous
Hello,

jbnh a écrit :Pour le nombre de ligne ....
Ou encore plus simplement :

#Include <File.au3>
_FileCountLines($sFilePath)

Re: [..]Nettoyer log

Posté : sam. 28 août 2010 20:24
par GELDROC
moi je ferai

Code : Tout sélectionner

$VAR = ""
dim $array
_FileReadToArray($filename, $array)

For $X = 1 to $Array[0]   
     $SPLIT = StringSplit($Array[X], "String a rechercher", 1)
     if $SPLIT[0] >= 1 then $VAR&= $Array[0]
Next

$hfile = fileopen($filename, 2)
filewrite($hfile, $VAR)
fileclose($hfile)
 
et comme ça ce script lit ligne par ligne puis réécrit le fichier avec seulement les ligne qui contienne le string spécifier

Re: [..]Nettoyer log

Posté : dim. 29 août 2010 00:21
par Tlem
A quoi va servir le fait de connaitre le nombre de lignes ?

Si c'est pour votre boucle de lecture (celle qui lit ligne par ligne), cela est totalement inutile.
@Error fera largement l'affaire. ;)
Voir l'exemple de l'aide de la commande FileReadLine.

Re: [..] Nettoyer log

Posté : dim. 29 août 2010 17:30
par sylvanie
idem sur la nécessité de connaître le nombre de ligne ?

Pour la supression des lignes "presques" doublons, il suffit de transformer l'écrèmage par pattern en tableau.
Puis on le tri afin de le parcourrir et de ne retenir que les éléments différents :
► Afficher le texte
NB : ce code présume que la machine peux contenir le log entier en ram. Si ce n'est pas le cas, il faudra l'adapter avec une lecture ligna à ligne.

Re: [..] Nettoyer log

Posté : mar. 31 août 2010 09:12
par softwater
Voici un bout de code qui me permet de ne conserver que les x (ici 200) dernières lignes de mon fichier log. Facile à adapter pour votre cas.
En bref, je copie l'entier du fichier log ligne par ligne dans un tableau, puis je ré-injecte les 200 dernière lignes dans un nouveau tableau qui est ensuite injecté dans un fichier log temp qui va remplacer l'original.
Il ne vous reste qu'à faire le code pour supprimer du tableau les éléments non voulus au niveau de la boucle
► Afficher le texte
Pour tester le code, créer un fichier "original.log" à l'emplacement du script et le remplir de texte.
Modifier la valeur de la variable "$conserv_line" pour définir le nombre de lignes à conserver.

Re: [..] Nettoyer log

Posté : mar. 31 août 2010 12:21
par SrBelial
idem :
suivant la taille du fichier : problème de consommation ressources, voire même problème de performances (alors que la complexité reste la même)

=> pour les besoins exprimés dans le début du sujet, la solution suivante reste sans doute la plus avantageuse :

lecture ligne à ligne
traitement de la ligne en cours (modification,extraction de données, ...)
si besoin de conserver la ligne : recopie dans un fichier temporaire
si besoin de supprimer la ligne : pas recopie
passage à la ligne suivante.
fin de fichier : on écrase l'ancien log avec le nouveau (à moins que l'on souhaite conserver l'ancien ...)

si on a besoin de connaitre le nombre de lignes, la solution donnée par moutelous est la plus simple à mettre en oeuvre

Code : Tout sélectionner

#Include <File.au3>
_FileCountLines($sFilePath)
@ricky : au vu des différentes solutions proposées ici, merci de confirmer que votre problématique est résolue en l'indiquant par la balise [R] en début de titre de votre premier message ^__^

Re: [R] Nettoyer log

Posté : mer. 01 sept. 2010 08:41
par ricky
Hello,

merci pour toutes ces solutions.
L'idée de réécrire dans un nouveau me plaît assez.
Le but de compter les lignes est de faire un rapport à la fin et le cas échéant y aller ligne par ligne pour être sur.

@sylvanie : impossible d'utiliser ton code, car dans le log c'est déjà trié par date et je ne peux pas trier que par une petite partie de la ligne car avant de supprimer il y a des conditions bien précises. Si je trie toutes les lignes presque identiques (sans tenir compte de la date et de l'heure), je ne peux en aucun cas les supprimer car je dois savoir ce qu'il y a dans les lignes d'avant et d'après. Surtout que la précision est à la milliseconde.