Bonjour à tous,
Dans le cadre de l'analyse de log, j'ai un fichier de +850000 lignes avec plusieurs colonnes.
Grosso modo, je l'ai réduit à ceci :
Pierre pierre.monsite.com 45
Paul paul.paulsite.com 10
Jacques jacques.sonsite.com 10
Pierre pierre.monsite.com 10
Jacques jacques.sonsite.com 0
Paul paul.paulsite.com 10
Toto toto.coco.com 1
…
J'aimerai pouvoir faire un tableau croisé dynamique : donc pouvoir sommer les utilisateurs pour n'avoir plus que
Pierre pierre.monsite.com 50
Paul paul.paulsite.com 20
etc…
Je l'ai fait avec des grep et des awks avec un fichier temporaire, mais c'est très lent et sans doute affreusement bateau.
De votre expérience pour ce genre de démarches, qu'utilisez-vous de rapide et si possible dispo de base dans les distrib serveurs ?
Merci pour vos trucs et astuces !
Ps : ce serait encore plus fort si ça gérait un nombre x de colonne :)
```
# un awk tout bête ?
Posté par Nicolas Casanova . Évalué à 3.
Hello,
Sur le petit échantillon que tu donnes, le code qui suit me paraît assez rapide ; il faudrait voir ce que ça donne sur sur tes 850 000 lignes.
Lapin compris cette partie-là ; tu veux dire que ton fichier en entrée n'a pas toujours un nombre fixé de colonnes ?
[^] # Re: un awk tout bête ?
Posté par Tristan Gallet . Évalué à 1.
Merci pour la piste, je ne maîtrise pas assez awk, comment puis je passer mon fichier dans ce script ?
J'ai fait ceci :
awk -f script-tri.awk < sorted.txt
awk: script-tri.awk:5: END {for (index in tableau)
awk: script-tri.awk:5: ^ syntax error
awk: script-tri.awk:6: print index, tableau[index]
awk: script-tri.awk:6: ^ syntax error
awk: script-tri.awk:6: fatal: invalid subscript expression
Il y a bien un nombre constant de colonne, du coup je pourrais faire le tri sur d'autres champs (nom mentionné ici).
J'avoue que si cela fonctionne comme ça, ça me parait lisible :)
[^] # Re: un awk tout bête ?
Posté par totof2000 . Évalué à 2.
Normalement, chmod +x script-tri.awk et ./script-tri.awk sorted.txt devrait suffire.
[^] # Re: un awk tout bête ?
Posté par Bernez . Évalué à 2.
Le mot « index » n'est pas utilisable comme nom de variable car c'est déjà un nom de fonction interne à awk. Remplace-le par « indice » et ça devrait fonctionner. Je ne sais pas comment Nicolas Casanova a fait pour le faire tourner tel quel.
[^] # Re: un awk tout bête ?
Posté par Tristan Gallet . Évalué à 1. Dernière modification le 05 mai 2014 à 12:09.
Bien joué, ça fonctionne !
C'est même tellement rapide que je suis étourdi :) -> je vais comparer à Excel et ses tableaux croisés dynamique !
Par contre, ça me donne une drôle de sortie : avec un fichier de log :
C'est un comportement normal ?
[^] # Re: un awk tout bête ?
Posté par Tristan Gallet . Évalué à 1.
[^] # Re: un awk tout bête ?
Posté par ✅ ffx . Évalué à 2. Dernière modification le 05 mai 2014 à 11:43.
Cela ressemble aux caractères spéciaux utilisés par awk comme séparateur de champs. Dans le script, remplace simplement
$1, " ", $2
par
$1" "$2
pour séparer avec des espacesou
$1","$2
pour séparer avec des virgules[^] # Re: un awk tout bête ?
Posté par Tristan Gallet . Évalué à 1.
Merci, j'ai tout mis en une ligne pour avoir le top 5:
awk -F, '{array[$5" "$6]+=$13} END { for (i in array) {print i" " array[i]}}' virus.csv | sort -nr -k3 | head -n5
Par contre, là je peux faire la somme pour une colonne, mais est-il possible de faire les sommes sur plusieurs colonnes ?
Begin Timestamp,End Timestamp,Begin Date,End Date,Sender IP Address,Hostname,DNS Verified,SBRS,Last Sender Group,Total Attempted,Stopped by Reputation Filtering,Stopped as Invalid Recipients,Spam Detected,Virus Detected,Stopped by Content Filter,Total Threat,Marketing,Clean
1393628400.0,1393714799.0,2014-02-28 23:00 GMT,2014-03-01 22:59 GMT,1.53.230.109,unknown domain,No,--,ALL,1,0,0,1,0,0,1,0,0
Du coup, je pourrais avoir un fichier avec l'IP comme index et avoir les Spam detected, Virus Detected et Total Threat en une seule fois ?
Pour info, le fichier virus.csv fait 122 mo et 856 000 ligne et est traité en environ 17s juste pour une colonne.
[^] # Re: un awk tout bête ?
Posté par NeoX . Évalué à 2.
tout ce joue là
tu dois bien pouvoir faire
ou carrement un tableau à 2 entrées
Attention ma syntaxe awk est imaginaire, la separation par ; et le tableau à 2 entrées sont des suppositions de ma part.
[^] # Re: un awk tout bête ?
Posté par ✅ ffx . Évalué à 2.
autant faire deux tableaux dans ce cas: array_spam[…] et array_virus[…]
[^] # Re: un awk tout bête ?
Posté par NeoX . Évalué à 2.
c'est corrigé
pour copier/coller du code, shell, perl ou autre il faut taper 3 ` suivi du langage, ca donne :
```sh
#!/bin/sh
moncode shell
avec
ses
fonctions
etc
etc
```
quand tu le tapes
et ca :
quand tu l'affiches.
et du coup ca gere les caracteres speciaux
attention il faut mettre un retour à la ligne avec les 3 `
# table de hash perl
Posté par NeoX . Évalué à 3.
un tableau de hashage perl avec la premiere colonne en clé et la 3e colonne en valeur
avec la valeur qui s'additionne à la precedente
# Perl
Posté par Tristan Gallet . Évalué à 1.
Pour perl, je ne connais pas assez, mais dans un site, il est noté :
"Vous l'avez sans doute compris, dans une table de hachage, une clef n'est présente qu'une seule fois et ne peut donc avoir qu'une seule valeur (comme l'élément d'un indice donné d'un tableau). Par contre, une valeur peut être associée à plusieurs clefs. "
Du coup, là j'ai plusieurs clés avec plusieurs valeur (on retrouve Pierre plusieurs fois avec plusieurs valeurs), mais peut-être ai-je mal compris ?
[^] # Re: Perl
Posté par chimrod (site web personnel) . Évalué à 2.
Oui (encore que ça dépend des langages), mais la table est mutable :
Si la clef n'est pas présente : tu insères dans ta table le couple (clef,valeur), et si la clef est déjà présente, tu met à jour ta table avec le couple (clef,valeur_actuelle+nouvelle_valeur).
[^] # Re: Perl
Posté par NeoX . Évalué à 4.
c'est exactement ca
mais "pierre" sera la clef, tu auras une seule "pierre" dans ton tableau
simplement à chaque fois que tu vois "pierre", il faudra faire un truc ressemblant à çà (attention ce n'est pas correct au niveau syntaxique perl)
ou
qui remplace donc la valeur courante (tableau['pierre'] à droite du =)
par la nouvelle valeur additionnée de la precedente.
quand tu as parcouru tout ton fichier de log,
tu as donc un tableau avec une ligne pour pierre, une ligne pour jean,
et une valeur tableau['pierre'] qui sera le total des lignes recontrées.
[^] # Re: Perl
Posté par Tristan Gallet . Évalué à 1.
Merci, je ne connaissais pas, je vais creuser aussi de ce côté.
Merci pour vos astuces, pour l'instant je prends la version awk, directement utilisable.
Bonne soirée à tous !
# SGBD
Posté par MrBidon . Évalué à 1. Dernière modification le 03 mai 2014 à 20:06.
Si tu en as un d'installé sur ta machine (MySQL, PostgreSQL ou MariaDB par exemple), charge ton CSV dans une table et fait une requête de ce genre :
[^] # Re: SGBD
Posté par Tristan Gallet . Évalué à 2.
Effectivement, c'est l'une des solutions que je voulais tester, mais par exemple sur pas mal d'appliances (dans ce cas un serveur mail Cisco) on trouve awk ou Perl mais pas une DB utilisable.
Beaucoup de suggestions intéressantes en tout cas, merci à tous.
```
[^] # Re: SGBD
Posté par jben . Évalué à 4.
Même sqlite ?
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.