我有分寸

一行的日志分析脚本

gnawux grepregexpscriptssed

为了分析hadoop的日志,特地写了个一行的程序,来分析日志程序。Hadoop 是个分布式程序,程序分布在多个节点上,日志自然也是多份的,这里用一行脚本提取所有日志中的关键内容,进行重新排序,方便跟踪,主要是 sed 应用

grep "blk_" hadoop-testhdp-* | sed -ne 's/^hadoop-testhdp-\([a-z]\{8\}\)-[a-z]\+-\([0-9]\{1,2\}-[0-9]\{1,2\}\).local.log[^:]*:\(20[0-9]\{2\}-1\?[0-9]-[0-9]\{1,2\} [0-9:,]\{10,12\}\)\(.*\)\(blk_-\?[0-9]\{19\}_[0-9]\{4\}\)\(.*\)$/ \5 \3 [\1] c\2: \4 [The BLK] \6/p'| sort |while read blk remain;do [ "$blk" != "$last" ] && echo "----------------" ; last=$blk ; echo $blk $remain ;done > blocks_log_seg.txt

这个程序主要有两个部分,while之前的是将所有日志放在一起,并提取每行的关键信息,重新排列,然后排序,这样就按照我们关心的方式来排列了,后面一部分(while)是将首个字段发生变化的位置标记出来,以方便查看。sed里面有这么一些关键点:

  • 指定某个表达式的长度:
    • \{8\} 8个长
    • \{10,12\} 10到12个长
    • \+ 至少一个长
    • \? 可能有一个
    • * 多少个都有可能,没有也有可能

  • ( ) 括起来的内容在后面依次可以用  \1, \2, \3…. 的方式来引用
  • 使用 [ ] 来指定可能的字符,或用 [^] 来排除没有的,如 [^:] 就是不包含冒号的,上述[^:]* 如果替换成 .* 的话,可能在 log: 2008-11-28 13:05:33 中做最大匹配,一直到33前面,红色部分的匹配可能是无门不希望看到的。

后面的 while 实际上保存了上一行的 $blk,然后和当前行作比较,如果不同就加如一行减号,从而分隔开不同的行,如果没有需要的话可以去掉,这样会运行得更快些。
注意,该程序的 while 部分在 linux 中运行速度尚可,在 cygwin 中几乎无法接受,如果用 cygwin 的话,建议要么去掉这部分,要么做好等很长时间的准备。

gnawux
me!#$!@#$@#$wangxu!@#$%^&*()_me