Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 29/09/2009, à 11:03

BorX

[Résolu] Shell : Optimisation : grep vs double-grep vs sed

Bonjour,

Je fais une repasse sur un Shell où il est question de parcourir un fichier de log pour compter le nombre de connexions et déconnexions à la date en cours.

Un premier grep consiste donc à sélectionner toutes les lignes comprenant le mot "Connexion" ou "Déconnexion".
De ce résultat, on ne garde que les lignes concernant la date en cours avec un second grep.
De ce résultat, on ne garde que le mot "Connexion" ou "Déconnexion" à l'aide de cut.
Et enfin, on trie et compte le nombre de mots avec sort et uniq.

$ time grep -E '(C|Déc)onnexion' fichier.log | grep $(date +%Y-%m-%d) | cut -d ' ' -f10 | sort | uniq -c
2390 Connexion
1938 Déconnexion

real    0m0,59s
user    0m0,48s
sys     0m0,02s

Ça marche, mais je trouvais que ça faisait beaucoup de commandes, et qu'il était possible d'optimiser tout ça...

J'ai donc cherché, dans un premier temps, à réunir les 2 grep :

$ time grep -E "$(date +%Y-%m-%d).*(C|Déc)onnexion" fichier.log | cut -d ' ' -f10 | sort | uniq -c
2390 Connexion
1938 Déconnexion

real    0m4,03s
user    0m3,02s
sys     0m0,03s

Surprise ! Son exécution est 4 fois plus lente !

Je me dis alors qu'un sed serait peut-être plus adapté (un seul sed remplace à lui tout seul les 2 grep et le cut) :

$ time sed -n "s/^.*$(date +%Y-%m-%d).* \(.*onnexion\).*$/\1/p" fichier.log | sort | uniq -c
2390 Connexion
1938 Déconnexion

real    0m7,65s
user    0m5,70s
sys     0m0,06s

Nouvelle surprise ! C'est encore pire !

Moralité, il vaut mieux utiliser 2 grep et un cut, plutôt qu'un sed ??
J'ai toujours cru qu'il valait mieux limiter le nombre d'enchaînements de processus, et qu'il fallait privilégier les awk/sed aux grep/tail/cut/...

Sauriez-vous m'expliquer pourquoi la première commande est finalement plus optimisée ?
Serait-ce mon sed que je n'ai pas bien agencé ??

Merci pour vos lumières...

Dernière modification par BorX (Le 29/09/2009, à 16:25)

Hors ligne

#2 Le 29/09/2009, à 11:29

Peck

Re : [Résolu] Shell : Optimisation : grep vs double-grep vs sed

Ton problème vient de l'utilisation de regex ainsi que de l'utilisation de .*

Hors ligne

#3 Le 29/09/2009, à 11:37

Coolgeek

Re : [Résolu] Shell : Optimisation : grep vs double-grep vs sed

Dans ta 1ere ligne de commande, je vois que tu les trie, y'a une raison particulière ?

Hors ligne

#4 Le 29/09/2009, à 12:07

BorX

Re : [Résolu] Shell : Optimisation : grep vs double-grep vs sed

Merci pour vos réponses rapides. smile

Coolgeek a écrit :

Dans ta 1ere ligne de commande, je vois que tu les trie, y'a une raison particulière ?

Oui : il convient d'utiliser sort avant d'utiliser uniq.

Peck a écrit :

Ton problème vient de l'utilisation de regex ainsi que de l'utilisation de .*

Intéressant.
J'utilise pourtant des regex dès la première commande : grep -E '(C|Déc)onnexion'
mais effectivement sans .*
Je comprends que l'utilisation de .* alourdisse la regex, mais comment s'en passer ? hmm

Hors ligne

#5 Le 29/09/2009, à 12:11

BorX

Re : [Résolu] Shell : Optimisation : grep vs double-grep vs sed

BorX a écrit :

Je comprends que l'utilisation de .* alourdisse la regex, mais comment s'en passer ? hmm

Peut-être que la réponse se trouve dans la question tongue
On s'en passe en séparant les recherches... D'où les 2 grep. C'est ça ? tongue

Hors ligne

#6 Le 29/09/2009, à 15:58

Peck

Re : [Résolu] Shell : Optimisation : grep vs double-grep vs sed

Tu peux peut-etre améliorer les choses avec perl et des regex utilisant .*?

D'autre part dans ta première ligne tu faisais uniquement rechercher suivi d'un cut, tu fais ensuite rechercher et remplacer ce qui implique des regex plus compliquées.

Enfin si tu utilise perl, tu peux passer l'intégralité de ta ligne en une seul ligne perl.

Hors ligne

#7 Le 29/09/2009, à 16:25

BorX

Re : [Résolu] Shell : Optimisation : grep vs double-grep vs sed

Merci pour ces conseils.
Je comprends le principe de lourdeur en utilisant .* (il parcourt chaque ligne caractère par caractère pour voir si la suite de la regex match).

Bref, j'étais resté dubitatif en constatant les perfs lamentable de ma commande sed, mais vous m'avez fourni l'explication, donc c'est parfait smile

Donc, je vais rester avec mes double-grep/cut et puis voilà ! smile

Et je vais revoir certains sed que j'emploie un peu trop avec des .* dans tous les sens.
A ce sujet, je patine : impossible de trouver le moyen de faire l'équivalent du grep -o. Mais ça fera l'objet d'un autre topic.

Merci à tous ! smile

Hors ligne

#8 Le 29/09/2009, à 22:23

AnsuzPeorth

Re : [Résolu] Shell : Optimisation : grep vs double-grep vs sed

Bjr,
Avec sed, l'équivalent de "grep -o" , je pense,

sed -n '/item/p' fichier.txt

Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script  (Hors ligne)

Hors ligne

#9 Le 30/09/2009, à 09:43

BorX

Re : [Résolu] Shell : Optimisation : grep vs double-grep vs sed

Merci pour l'idée.
L'inconvénient, c'est que l'action 'p' de sed renvoie toute la ligne, et pas seulement ce qu'on recherche.

Grosso modo, je voudrais faire ça, mais sans les .* :

sed -n 's/^.*\(regex\).*$/\1/p' fichier.txt

Ce qu'on fait simplement avec un grep -Eo :

grep -Eo "regex" fichier.txt

Hélas, développant sous AIX, je ne dispose pas d'une version de grep suffisamment avancée.
Effectivement, une solution perl serait un bonne alternative, mais je me demandais si sed possédait une autre action que 'p' consistant à n'afficher que ce qui est demandé, et pas toute la ligne.

Dernière modification par BorX (Le 30/09/2009, à 09:44)

Hors ligne

#10 Le 30/09/2009, à 17:05

Totor

Re : [Résolu] Shell : Optimisation : grep vs double-grep vs sed

Bonjour,

Pourquoi la version sed ne te convient pas ?
j'ai un AIX sous la main (jusqu'à ce soir...après je sais pô) et ceci fonctionne :

awk ' {outLine="";while (match($0,/toto/) > 0) {outLine=outLine " " substr($0,RSTART,RLENGTH);sub(/toto/,"")}; print outLine}' <<< "toto totoa iti toto"

change /toto/ par ton ERE...


-- Lucid Lynx --

Hors ligne

#11 Le 30/09/2009, à 17:12

BorX

Re : [Résolu] Shell : Optimisation : grep vs double-grep vs sed

Cette nuit, j'ai rêvé que Totor me répondait... et Totor l'a fait ! smile

La version sed me convient en théorie, mais les performances sont désastreuses, vraisemblablement à cause de l'utilisation abusive de .*
Aussi, je cherchais un moyen de faire du sed (généralement préférable à l'accumulation de grep) de façon un peu plus optimisé.

Tu réponds (peut-être) à ma question, par une commande qui me dépasse pour le moment.
Merci. Je vais comparer les perfs de chacune des commandes pour faire mon choix entre le plus rapide et le plus élégant. smile

Hors ligne

#12 Le 30/09/2009, à 18:17

BorX

Re : [Résolu] Shell : Optimisation : grep vs double-grep vs sed

Ingénieux, finalement assez simple quand on se penche dessus (le substr($0,RSTART,RLENGTH) m'échappe encore un peu)... et efficace (a priori aussi rapide qu'un grep) !
Après adaptation, je vais certainement l'adopter tongue
Merci ! smile

Dernière modification par BorX (Le 30/09/2009, à 18:17)

Hors ligne

#13 Le 30/09/2009, à 18:43

BorX

Re : [Résolu] Shell : Optimisation : grep vs double-grep vs sed

Mon script awk n'est certainement pas optimisé et pourtant on sent déjà une différence : smile

$ time awk '{
  cpt=1
  while (cpt <= 2 && match($0, /Current thread busy: ([0-9]*)/) > 0) {
    if (cpt < 2) sub(/Current thread busy: ([0-9]*)/, "")
    else print substr($0, RSTART + 21, RLENGTH - 21)
    cpt++
  }
}' status.txt
2

real    0m0.028s
user    0m0.030s
sys     0m0.015s

$ time sed -n 's/^.*Current thread busy: \([0-9]*\).*$/\1/p' status.txt 
2
real    0m0.040s
user    0m0.046s
sys     0m0.046s

Dernière modification par BorX (Le 30/09/2009, à 18:44)

Hors ligne

#14 Le 30/09/2009, à 20:21

Totor

Re : [Résolu] Shell : Optimisation : grep vs double-grep vs sed

BorX a écrit :

[...]le substr($0,RSTART,RLENGTH) m'échappe encore un peu[..]

Cela permet d'extraire de $0 le motif détecté par match
En effet, match retourne l'indice de l'expression recherchée dans la chaine demandée mais valorise aussi la variable RSTART par cet indice et RLENGTH avec la longueur de la chaine trouvée correspondant au motif recherché.


-- Lucid Lynx --

Hors ligne

#15 Le 01/10/2009, à 10:11

BorX

Re : [Résolu] Shell : Optimisation : grep vs double-grep vs sed

awk is my new religion ; Totor is my prophet.

Hors ligne