Oneliner для расчета полного размера всех сообщений в почтовом журнале - PullRequest
1 голос
/ 16 ноября 2010

Хорошо, ребята, я действительно в тупике, не знаю, что еще попробовать ...

Я пишу скрипт для некоторой статистики электронной почты, одна из вещей, которую он должен сделать, это вычислить полный размер всех сообщений в почтовом журнале, вот что я написал до сих пор:

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

А вот пример строки из моего почтового журнала:

Nov 15 09:08:48 HOSTNAME sendmail[3226]: oAF88gWb003226:  
from=<name.lastname@domain.com>, size=40992, class=0, nrcpts=24,  
msgid=<E08A679A54DA4913B25ADC48CC31DD7F@domain.com>, proto=ESMTP,  
daemon=MTA1, relay=[1.1.1.1]

Итак, я постараюсь объяснить это шаг за шагом:

Сначала я пролистываю файл, чтобы найти все строки, содержащие фактический «размер», затем я печатаю 8-е поле, в данном случае «size = 40992».

Далее я заменяю все символы запятой знаком плюс.

Затем я удаляю все, кроме цифр и знака плюс.

Затем я заменяю начало строки на "(", а последний дополнительный знак плюс заменяю на ")", за которым следует "/ 1048576". Итак, я получаю огромное выражение, похожее на это:

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

Потому что я хочу сложить все отдельные размеры сообщений и разделить их, чтобы получить результат в МБ.

Последняя команда awk, когда я получаю десятичное число, мне действительно не нужна точность, поэтому я просто печатаю часть перед десятичной точкой.

Проблема в том, что это не работает ... И я могу поклясться, что это сработало в один момент, может быть, мое выражение слишком длинное, чтобы bc мог его обработать?

Спасибо, если вы нашли время, чтобы прочитать:)

Ответы [ 2 ]

4 голосов
/ 16 ноября 2010

Я думаю, что однострочный awk скрипт тоже будет работать. Он соответствует любой строке, которой соответствует ваш шаблон egrep, затем для этих строк разбивает восьмую запись знаком = и добавляет вторую часть (число) к переменной SUM. Когда он видит КОНЕЦ файла, он печатает значение SUM / 1048576 (или количество байтов в мибибайтах).

awk '/ HOSTNAME sendmail\[.*.from=.*., size=/{ split($8,a,"=") ; SUM += a[2] } END { print SUM/1048576 }' maillog
1 голос
/ 16 ноября 2010
  • bc дросселирует, если в его входе нет новой строки, как это происходит с вашим выражением. Вы должны изменить часть sed на:

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

  • Последний awk с удовольствием съест все ваши выходные данные, если общий размер меньше 1 МБ, а bc выдает что-то вроде .03333334234. Если вас не интересует десятичная часть, удалите последнюю команду awk и параметр -l из bc.

  • Я бы сделал это с помощью одной строки:

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

...