一个Liner计算maillog中所有消息的完整大小

时间:2010-11-16 00:52:23

标签: bash sed awk grep bc

好的家伙,我真的死在这里,不知道还有什么可以尝试......

我正在为一些电子邮件统计编写一个脚本,它需要做的一件事是计算maillog中所有消息的完整大小,这是我到目前为止写的:

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

这是我maillog的一个示例行:

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 ... + N)/ 1048576”

因为我想将所有单独的邮件大小相加并除以它,所以我得到MB的结果。

最后一个awk命令是当我得到一个十进制数字时我真的不关心精度所以我只是在小数点之前打印部分。

问题是,这不起作用......而且我可以发誓它曾经在某一点工作,难道我的表达对于bc来说太长了吗?

谢谢你花时间阅读:)

2 个答案:

答案 0 :(得分:4)

我认为单行awk脚本也可以使用。它匹配你的egrep模式匹配的任何行,然后对于那些行,它将第八个记录分割为=符号,并将第二个部分(数字)添加到SUM变量。当它看到文件的END时,它会输出SUM / 1048576的值(或以Mibibytes为单位的字节数)。

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

答案 1 :(得分:1)

  • 如果输入中没有换行符,则会阻塞bc,就像你的表达式一样。您必须将sed部分更改为:

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

  • 如果总大小小于1MB并且bc输出类似于.03333334234的内容,那么最后的awk将很乐意吃掉所有输出。如果您对小数部分不感兴趣,请从bc中删除最后一个awk命令和-l参数。

  • 我会用这个单行代码来做:

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 |' | BC