导读 在对日志信息进行实时监控分析时,需要对日志中纳秒级的时间进行计算,逻辑比较简单:找出开始时间、结束时间,遇到结束时间后输出时间间隔。

在对日志信息进行实时监控分析时,需要对日志中纳秒级的时间进行计算,逻辑比较简单:找出开始时间、结束时间,遇到结束时间后输出时间间隔。
日志中的部分数据如下:

2016-01-30 19:37:30 1454153850967748663 remove alive file  2016-01-30 19:37:34 1454153854621122459 role change to FAULT

一开始写出来是这样的:

awk '  /remove alive file/ {    start=$3    printf "%6s: %dn","START",start  }  /role change to FAULT/ {    end=$3;    printf "%6s: %dn","END",end    diff=(end-start)/1000^3    printf "%6s: %0.9f(s)n","DIFF",diff  }'

输出结果看似就是我想要的:

 START: 1454153850967748608     END: 1454153854621122560    DIFF: 3.653373952(s)

有的朋友可能看到这个结果后就直接使用了,但是较真的我还是把输出结果和bc的结算结果比较了一下,没问题。

接下来我习惯性的到日志中把每个输出结果进行确认,略一看没什么不对的地方,仔细一对比,发现日志中纳秒级的时间被awk处理后竟然变了。为了进行确认,写了如下代码:

awk 'BEGIN {    printf "%20s == %-20sn","0X2FFFFFFFFFFFFF","13510798882111487"    printf "%20X    %dn",0X2FFFFFFFFFFFFF,0X2FFFFFFFFFFFFF    printf "%20X    %dn",13510798882111487,13510798882111487    printf "---------------------------------------------n"    printf "%20s == %-20sn","0X2FFFFFFFFFFFFE","13510798882111486"    printf "%20X    %dn",0X2FFFFFFFFFFFFE,0X2FFFFFFFFFFFFE    printf "%20X    %dn",13510798882111486,13510798882111486  }'

输出结果如下:

0X2FFFFFFFFFFFFF == 13510798882111487        30000000000000    13510798882111488        30000000000000    13510798882111488  ---------------------------------------------      0X2FFFFFFFFFFFFE == 13510798882111486        2FFFFFFFFFFFFE    13510798882111486        2FFFFFFFFFFFFE    13510798882111486

对应的二进制数值如下:

0X30000000000000: 11 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000  0X2FFFFFFFFFFFFF: 10 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111  0X2FFFFFFFFFFFFE: 10 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110

发现awk的数值处理范围超过0X2FFFFFFFFFFFFE(13510798882111486)就不不准确了(为了找这个临界值,费了一番功夫),他会把0X2FFFFFFFFFFFFF当成0X30000000000000,如果在awk中对0X2FFFFFFFFFFFFF进行减一计算,值没有任何变化,对0X2FFFFFFFFFFFFE进行加法运算,加1和加2的结果都是0X30000000000000,但是awk又可以显示/处理更大的数值,从二进制结果中我也没看出有什么规律可循。有兴趣的可以深入源码层面研究下。

接下来,毅然放弃awk自身的计算功能,选择awk与bc的结合。于是,把代码修改成下面的样子:

awk '  /remove alive file/ {    start=$3    printf "%6s: %sn","START",start

本文原创地址:https://www.linuxprobe.com/awk-bug.html编辑:public,审核员:暂无

本站所发布的一切资源仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如果侵犯你的利益,请发送邮箱到 [email protected],我们会很快的为您处理。
超哥软件库 » 惊现 awk bug!