parser logs avec AWK

parser logs avec AWK - Shell/Batch - Programmation

Marsh Posté le 29-08-2006 à 17:05:40    

Hello,
 
J'ai un petit soucis avec des logs que je dois parser.
J'ai pour habitud d'utiliser awk pour faire cette tache mais la je ne m'en sors pas...
normalement je lis le fichier ligne par ligne et j'extrai les champs qui m'interessent, mais cette fois ci, une connexion prend deux lignes.
par contre , il y'a un champ id qui permet d'identifier les lignes qui representes la meme connexion.
 
exemple:
 
id=1 etat=debut champ2=x champ3=x champ4=x   //debut connexion
id=2 etat=debut champ2=x champ3=x champ4=x
id=3 etat=debut champ2=x champ3=x champ4=x
id=1 etat=fin champ6=x champ7=x champ8=x       //fin connexion
id=4 etat=debut champ2=x champ3=x champ4=x
id=2 etat=fin champ6=x champ7=x champ8=x
id=3 etat=fin champ6=x champ7=x champ8=x
id=4 etat=fin champ6=x champ7=x champ8=x
 
donc en gros, il y'a 2 enregistrements, un pour le debut avec des champs à recuperer, et un pour la fin avec des champs à recuperer, et ces deux lignes on le meme id.
 
Comment obtenir un dans un fichier resultat tous les champs sur une meme ligne pour chaque connexion:
 
id=1 champ2=x champ3=x champ4=x champ6=x champ7=x champ8=x
id=2 champ2=x champ3=x champ4=x champ6=x champ7=x champ8=x
id=3 champ2=x champ3=x champ4=x champ6=x champ7=x champ8=x
id=4 champ2=x champ3=x champ4=x champ6=x champ7=x champ8=x
 
 
merci d'avance

Reply

Marsh Posté le 29-08-2006 à 17:05:40   

Reply

Marsh Posté le 29-08-2006 à 17:42:58    

j'aurais foutu ca dans une Bdd a l'ancienne

Reply

Marsh Posté le 29-08-2006 à 18:07:54    

mode perl hardcode ( oui j'avais envie de me détendre au taf :o ):

Code :
  1. perl -00 -ne '@m=( /(id=\d+).*?(?![etat])(([\w|\d]+=[\w|\d]+ *)+)/g);for($i=0;$i<=$#m;$i+=3){$h{$m[$i]}.=$m[$i+1];}foreach(sort keys %h){print $_." ".$h{$_}."\n";}' tonFichier


Message édité par anapajari le 29-08-2006 à 18:09:10
Reply

Marsh Posté le 29-08-2006 à 23:45:41    

arf, j'ai pas tout compri à ton code :)
mais merci je vais me plonger dedans
 
sachant qu'il peut y avoir 5 000 000 de lignes dans le fichier, donc a priori c'est delicat d'utiliser des tableaux de memoire , nan ?

Reply

Marsh Posté le 30-08-2006 à 09:05:49    

étant donné que tu veux "concatener" différentes lignes qui sont en différents endroits de ton fichier tu va avoir du mal à faire autrement [:spamafote].
Par contre je suis sur que c'est effectivement optimisable!
 
Pour un fichier de 5M lignes, ça dépend de ton serveur mais normalement ça doit bien se passer!

Reply

Marsh Posté le 30-08-2006 à 09:49:56    

j'ai bcp de mal a comprendre ce passage la :  .*?(?![etat])

Reply

Marsh Posté le 30-08-2006 à 10:01:08    

c'est de la regex bien goret! Mais il faut la suite pour bien comprendre:
.*?(?![etat])[\w|\d]+=[\w|\d]+
En gros ça veut dire: "N'importe quoi jusqu'a ce que tu trouves "un mot=un mot" mais le premier mot ne doit pas être "etat".
le ?! ça s'appele une assertion négative.

Reply

Marsh Posté le 30-08-2006 à 12:15:10    

une derniere chose , a quoi sert le "$#m" et le /g ?
merci d'avance

Reply

Marsh Posté le 30-08-2006 à 16:06:36    

anapajari a écrit :

étant donné que tu veux "concatener" différentes lignes qui sont en différents endroits de ton fichier tu va avoir du mal à faire autrement.


Il est tout à fait possible de traiter le problème sans avoir recours à un tableau en mémoire.
Si l'on suppose que toutes les lignes du fichier commencent par "id=" et que pour chaque valeur d'id il y a une et une seule ligne début et fin :

sort -k1.4n -k2 tonFichier |  
awk '
  {
   line = $0;
   getline;
   $1 = $2 = "";
   line = line FS $0;
   gsub(FS "+",FS, line);
   print line;
  }'


Par contre, je ne sais pas ce que cela donne en terme de performances par rapport à la solution perl.
 
Jean-Pierre.

Reply

Marsh Posté le 30-08-2006 à 16:21:25    

clancy a écrit :

une derniere chose , a quoi sert le "$#m" et le /g ?
merci d'avance


$#m = taille du tableau m
/g option d'une regex pour lui dire de prendre tous les motifs trouvés ( en fait de pas s'arreter au 1er)

aigles a écrit :

Il est tout à fait possible de traiter le problème sans avoir recours à un tableau en mémoire.
Si l'on suppose que toutes les lignes du fichier commencent par "id=" et que pour chaque valeur d'id il y a une et une seule ligne début et fin :


Jamais dit le contraire :D
Sauf qu'a mon avis il est jamais sur de savoir s'il y a un ou plusieurs lignes pour chaque id (même si plusieurs = 2)


Message édité par anapajari le 30-08-2006 à 16:22:15
Reply

Marsh Posté le 30-08-2006 à 16:21:25   

Reply

Marsh Posté le 30-08-2006 à 19:28:40    

en fait, il y'a bien une seule ligne pour le debut et une seule pour la fin :)
aigles serait-il possible que tu m'expliques un peu ton code ?  
merci d'avance

Reply

Marsh Posté le 30-08-2006 à 21:33:09    

c'est bon j'ai compris :)


Message édité par clancy le 30-08-2006 à 21:35:06
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed