Bash : compter les heures, ajouter un 0 devant une heure inférieure à 10

Twitter Facebook Google Plus Linkedin email

J’ai été confronté à un problème simple à la base (pour un adminsys) : compter le nombre de requêtes sur un site, heure par heure, à partir d’un fichier access_log Apache. Finalement le problème était un peu plus tricky, et ça demande un peu plus d’explications qui ne tiennent pas dans une astuce diverse.

 Le log apache est facile à lire via bash, il contient la date et l’heure dans un format que grep n’aura aucun mal à identifier. Je shoot donc un one-liner rapide :

Simple, rapide, efficace, le quotidien du sysadmin quoi. Enfin efficace… Le résultat est sur le coup surprenant :

Damned. J’imagine mal un site public sous WordPress capable de ne pas subir la moindre requête pendant plusieurs heures, entre monitoring, intervention client ou robots d’indexation. J’ai donc fait une connerie. Une connerie vite identifiée vu le pépin : l’heure est notée sur deux chiffres dans les logs, hors il n’y a que 0,1,2 qui peuvent matcher dans ce cas, ce qui explique les trous de 3 à 9.

Certains furieux trouveraient certainement une regex ultra cradingue à exploiter à la place (et faut pas hésiter à partager en commentaires), j’ai fait un peu différent (c’est surtout pour ça que je voulais en parler), à savoir passer deux ensembles de nombres à for :

C’est beaucoup mieux.

Oui, on peut indiquer deux plages de valeurs sans avoir à faire deux boucles. Une bizarrerie découverte au hasard d’une recherche de solution à mon petit souci. En fait, dans la pratique les deux ensembles sont décomposés par Bash pour ne constituer qu’une seule liste, ce qui donne l’équivalent de la syntaxe suivante, bien plus longue et lente à écrire :

Ce langage ne cesse de m’étonner, j’ai l’impression qu’on pourrait y passer une vie sans en avoir fait le tour.

Bon ça m’empêchera pas de continuer à m’intéresser à PHP et Python 😛

5
Poster un Commentaire

avatar
5 Fils de commentaires
0 Réponses de fil
2 Abonnés
 
Commentaire avec le plus de réactions
Le plus populaire des commentaires
5 Auteurs du commentaire
DasFranckDavid_5.1SaeroshiÉlectronLiandri Auteurs de commentaires récents
  S’abonner  
plus récent plus ancien
Notifier de
Liandri
Invité
Liandri

Et l’heure 0? :0

Électron
Invité
Électron

Y’a encore mieux, en fait.
Pour faire la liste tu peux simplement utiliser {00..23}, pour les valeurs de 0 à 9 bash va automatiquement insérer un 0 au début 🙂

Saeroshi
Invité
Saeroshi

Bonjour à toi,

Tu peux aussi utiliser la commande seq -w 23 (ou seq -w 0 23)

Saeroshi.

David_5.1
Invité
David_5.1

En plus compliqué : for i in {0..23}; do echo -ne "${i}h : $(grep "2017:$(printf '%02d' $i):" access.log |wc -l)n"; done Dans ce cas, c’est pas très utile, mais dans d’autres, ça peut, par exemple si on veut jouer avec de l’hexadécimal : for i in {0..255}; do printf '%02x ' $i; done' Dans tous les cas, le grep est peu précis et il pourrait matcher le user agent d'un troll… Aussi, logrotate (ou équivalent) peut passer et fausser les résultats. Je ferais plutôt :mawk ‘{gsub(« : »,  » « , $5); count[substr($5, 2, 14) »h: »]++} END {for (date in count) print date, count[date]}’… Lire la suite »

DasFranck
Invité

Petite coquille à la fin sur la ligne de script shell : ‘for in in « 00 » « 01 » « 02 » « 03 » « 04 » « 05 » … « 23 »; do …’
Je crois pas que bash tolère les doubles in, ça doit juste être un i travesti en in.

Article sympathique sinon. 🙂