2011-09-19 97 views
0

我有线这样的日志文件:DIFF时间戳命令

...timestamp...(id=1234)..GO... 
...timestamp...(id=1234)..DONE... 

事实:

  • 时间戳形式的HH:MM:SS.ssss( s为部分秒)
  • 每个'id'号码具有两个相关联的行,“GO”和“DONE”两条相关联的行不一定彼此相邻;该文件是按时间顺序

我想要什么:

  • 投其所好相关GO/DONE线
  • DIFF时间戳
  • (理想)创建的窗体的新文件:

    diffTime <GO line> <DONE line> 
    

我的主sti cking点正在区分时间戳。这将是非常有用的,我缺乏sort/sed/awk技能来编写它。有没有日志文件工具来帮助这种黑客行为?

+0

如果你有机会获得GNU的awk的

  • 计算时间差异,那么你有[时间戳功能](http://www.delorie.com/gnu/docs /gawk/gawk_138.html)在您的处置。 – Johnsyweb

  • 回答

    2

    我不知道任何这样的工具,但也可以把它写在外壳。例如,此日志:

     
    11:18:51 (id=123) GO 
    11:18:52 (id=124) GO 
    11:18:53 (id=123) DONE 
    11:18:54 (id=125) GO 
    11:18:55 (id=125) DONE 
    11:18:55 (id=124) DONE 
    

    可以转化为

     
    2 123 
    3 124 
    1 125 
    

    其中第一列是时间(秒)和第二列是一个事务ID。

    命令:

    cat example.log 
    | sed 's|\([^ ]\+\) (id=\([^)]\+\)) \(.\+\)|\1 \2 \3|;s|GO|1|;s|DONE|2|' 
    | sort -k2,3 
    | paste - - 
    | tr ':' ' ' 
    | awk '{printf("%d %d\n", ((($6-$1)*60*60)+(($7-$2)*60)+($8-$3)), $4)}' 
    

    这一个班轮或许可以更简化。

    工作原理:

    • 变线格式“十一时18分51秒123 GO”
    • 替换1去和2完成(因为在后,它允许我们正确排序的话)
    • 各种导致通过事务ID和状态线
    • 加入各2行(现在每个结果行描述事务处理开始,结束)
    • 更换所有冒号为空格(为了简化awk expessions升亚特)通过手动将
    • 打印结果
    2

    这里有一个脚本,将让你中途有:

    #!/bin/bash 
    
    # Script must be called with one parameter, the name of the file to process 
    if [ $# -ne 1 ]; then 
        echo "Usage: $0 filename" 
        exit 
    fi 
    
    filename=$1 
    
    
    # Use sed to put the timestamp after the id 
    # 10:46:01:0000 (id=20) GO 
    # 10:46:02:0000 (id=10) GO 
    # 10:46:03:0000 (id=10) DONE 
    # 10:46:04:0000 (id=20) DONE 
    # 
    # becomes 
    # 
    # (id=20) 10:46:01:0000 GO 
    # (id=10) 10:46:02:0000 GO 
    # (id=10) 10:46:03:0000 DONE 
    # (id=20) 10:46:04:0000 DONE 
    # 
    # \1 timestamp 
    # \2 id 
    # \3 status (GO or DONE) 
    #   \1   \2    \3 
    sed -e "s/\([0-9:]*\) \((id=[0-9]*)\) \(.*\)/\2 \1 \3/" $filename > temp1 
    
    
    # Now sort the file. This will cause timestamps to be sorted, grouped by id 
    # (id=20) 10:46:01:0000 GO 
    # (id=10) 10:46:02:0000 GO 
    # (id=10) 10:46:03:0000 DONE 
    # (id=20) 10:46:04:0000 DONE 
    # 
    # becomes 
    # 
    # (id=10) 10:46:02:0000 GO 
    # (id=10) 10:46:03:0000 DONE 
    # (id=20) 10:46:01:0000 GO 
    # (id=20) 10:46:04:0000 DONE 
    sort temp1 > temp2 
    
    
    # Use sed to put the id after the timestamp 
    # (id=10) 10:46:02:0000 GO 
    # (id=10) 10:46:03:0000 DONE 
    # (id=20) 10:46:01:0000 GO 
    # (id=20) 10:46:04:0000 DONE 
    # 
    # becomes 
    # 
    # 10:46:02:0000 (id=10) GO 
    # 10:46:03:0000 (id=10) DONE 
    # 10:46:01:0000 (id=20) GO 
    # 10:46:04:0000 (id=20) DONE 
    # \1 id 
    # \2 timestamp 
    # \3 status (GO or DONE) 
    sed -e "s/\((id=[0-9]*)\) \([0-9:]*\) \(.*\)/\2 \1 \3/" temp2 > temp3 
    

    至于其他...运行此脚本后,各走各的线之后,将具有相同ID的DONE线,假设这样的一个DONE行存在。

    接着可以读取每对线,提取时间戳和diff的它们(检查出的时间戳函数Johnsyweb建议的)。然后将两条线合并成一条线。您的结果现在看起来如下所示:

    # 1s 10:46:02:0000 (id=10) GO 10:46:03:0000 (id=10) DONE 
    # 3s 10:46:01:0000 (id=20) GO 10:46:04:0000 (id=20) DONE 
    

    请注意,条目在起始时间戳记中是如何排序的。发生这种情况是因为我们之前按id排序。我将把它作为练习,让你了解如何以正确的顺序获取参赛作品。我们希望为ID = 20来ID = 10之前进入,因为ID = 20是ID = 10之前开始。

    # 3s 10:46:01:0000 (id=20) GO 10:46:04:0000 (id=20) DONE 
    # 1s 10:46:02:0000 (id=10) GO 10:46:03:0000 (id=10) DONE 
    

    我敢肯定,这是令人困惑的,所以让我知道如果你有问题。我敢肯定,有更高效的方法可以做到这一切,但是这是我想到了我的头顶。

    +1

    您可以摆脱第一个'sed'步骤,并直接按第二个字段排序:'sort -k2 ...'。另外,如果有多个具有相同ID和时间戳的条目,我会添加'-s'选项以使排序稳定。 –