2010-11-16 3 views
1

Ok les gars, je suis vraiment dans une impasse ici, ne sais pas quoi d'autre pour essayer ...Oneliner pour calculer la taille complète de tous les messages dans maillog

Je suis en train d'écrire un script pour un e-mail statistiques, l'une des choses dont il a besoin de faire est de calculer la taille totale de tous les messages du maillog, c'est ce que je l'ai écrit jusqu'à présent:

egrep ' HOSTNAME sendmail\[.*.from=.*., size=' maillog | awk '{print $8}' | 
tr "," "+" | tr -cd '[:digit:][=+=]' | sed 's/^/(/;s/+$/)\/1048576/' | 
bc -ql | awk -F "." '{print $1}' 

Et voici une ligne d'échantillon de mon maillog:

Nov 15 09:08:48 HOSTNAME sendmail[3226]: oAF88gWb003226: 
from=<[email protected]>, size=40992, class=0, nrcpts=24, 
msgid=<[email protected]>, proto=ESMTP, 
daemon=MTA1, relay=[1.1.1.1] 

Alors je vais t Premièrement, je passe en revue le fichier pour trouver toutes les lignes contenant la «taille» réelle, ensuite j'imprime le 8e champ, dans ce cas «taille = 40992».

Ensuite, je remplace tous les virgules par un signe plus. Ensuite, je supprime tout sauf les chiffres et le signe plus.

Ensuite, je remplace le début de la ligne par un "(", et je remplace le dernier signe plus avec un ")" suivi de "/ 1048576". Donc, je reçois une énorme expression qui ressemble à ceci:

"(1 + 2 + 3 + 4 + 5 ... + n)/1048576"

Parce que je veux ajouter toutes les tailles de messages individuels et divisez-le donc j'obtiens le résultat en MB.

La dernière commande awk est quand j'obtiens un nombre décimal je ne me soucie vraiment pas de la précision, donc j'imprime simplement la partie avant le point décimal. Le problème est, cela ne fonctionne pas ... Et je pourrais jurer qu'il fonctionnait à un moment donné, pourrait-il être mon expression est trop longue pour que bc manipule?

Merci si vous avez pris le temps de lire :)

Répondre

4

Je pense qu'un script awk à une ligne fonctionnera aussi. Il correspond à n'importe quelle ligne correspondant à votre modèle egrep, puis pour ces lignes il sépare le huitième enregistrement par le signe = et ajoute la deuxième partie (le nombre) à la variable SUM. Lorsqu'il voit la fin du fichier, il imprime la valeur de SUM/1048576 (ou le nombre d'octets dans Mibibytes).

awk '/ HOSTNAME sendmail\[.*.from=.*., size=/{ split($8,a,"=") ; SUM += a[2] } END { print SUM/1048576 }' maillog 
+0

Wow, merci beaucoup, c'est une bonne approche et cela fonctionne incroyablement vite! Juste ce que je cherchais :) – f10bit

+0

+1 C'est aussi beaucoup plus rapide. La seule raison pour laquelle je suis allé avec les choses grep/sed/tr/bc ci-dessus était parce que c'était plus proche de la doublure de la question – thkala

1
  • bc selfs s'il n'y a pas de nouvelle ligne dans son entrée, comme cela se passe avec votre expression. Vous devez changer la partie sed:

sed 's/^/(/; s/+/$) \/1048576 \ n /'

  • La awk finale se fera un plaisir de manger toute votre sortie si la taille totale est inférieure à 1 Mo et bc produit quelque chose comme 0,03333334234. Si la partie décimale ne vous intéresse pas, supprimez la dernière commande awk et le paramètre -l de bc.

  • que je le ferais avec celui-liner: [[0-9] * [0-9]]

grep 'hostname sendmail: .. *. * From =. . *, size = 'maillog | sed 's |. *, size = \ ([0-9] [0-9] * \),. * | \ 1+ |' | tr -d '\ n' | sed 's |^| (|; s | $ | 0)/1048576 \ n |' | bc

+0

Merci pour cette réponse rapide et complexe! Hmmm, il semble que ce n'est pas seulement dans le retour à la ligne, ajouté comme vous l'avez suggéré, obtenez toujours "(standard_in) 1: erreur d'analyse". Essayé votre code, malheureusement, il ne fonctionne pas, je reçois un: "sed: -e expression # 1, char 31: référence invalide \ 1 sur RHS de la commande" – f10bit

+0

@ f10bit désolé, StackOverflow a mangé quelques caractères ici et là, s'il vous plaît essayer à nouveau – thkala

+0

@ f10bit: ajouter un \ n après le 1048576 dans votre commande d'origine semble bien fonctionner ici – thkala

Questions connexes