sed and awk 对nginx日志操作

因为刚接触awk操作,所以对字符串处理很悲催,使用sed来替换双引号中的空格做不到(如果能做到,计算速度会大大增加),下面列出一个nginx的日志格式,因为日志格式自己可以修改,所以不定每个格式都相同!

220.181.108.121 - - [30/Oct/2011:00:11:45 +0800] "GET /deal-ask.htm?id=2285&page=6 HTTP/1.1" 499 0 "-" "Baiduspider-image+(+http://www.baidu.com/search/spider.htm)" - -> --

1,客户端ip
2,- (未知)
3,- (未知)
4,访问时间
5,访问形式和访问页面
6,http状态码
7,浏览器加载数据量
8,来源页
9,客户端浏览器
10,客户端代理ip(有时候可多个)
11,之后都只我们自己设置的用户唯一识别码目的是为了跟踪用户轨迹!多加一个"-"为了识别新老用户!这也是技巧!

下面是我使用shell对这段文字的处理

  1. #!/bin/sh
  2. if [ $# -ne 1 ] || [ ! -f $1 ]
  3. then
  4.     echo 'Warnning:"Incorrect number of parameters setted only one and must be a file type"' >&2;
  5.     exit 1;
  6. fi;
  7. start=`date +%s%N`;
  8. errFile='./lag.txt';#error data file
  9. file=$1;
  10. /bin/echo 'Script running! please wait ....' 1>&2;
  11. #sed '/\(^[0-9]\{1,3\}\.\)\{1,3\}[0-9]\{1,3\}/ s/\(\([0-9]\{1,3\}\.\)\{1,3\}[0-9]\{1,3\},\)/\1/g;/\[[2-3]\{1\}[0-9]\{1\}/s/\//-/g;s/ +0800\]/]/' $file | \
  12. sed 's/\(\([0-9]\{1,3\}\.\)\{1,3\}[0-9]\{1,3\},\) /\1/g;/\[[2-3]\{1\}[0-9]\{1\}/s/\//-/g;s/ +0800\]/]/' $file | \
  13. awk 'BEGIN{FS="\"";}{for(i=1;i<=NF;i++){if(i%2==1) gsub(" ","\t",$i);printf "%s",$i (i==NF?RS:FS);}}'| \
  14. awk 'BEGIN{n=0;FS="\t";}{
  15.         #Check the regular expression is correct or not
  16.         if($11!="->"){print $0;print NR;exit;}
  17.         if($12=="--"){#redirect to ./lag.txt file
  18.             gsub("\t"," ",$0);
  19.             print $0" "NR> errFile;
  20.         }else{
  21.             isNew = $12~/-/?(substr($12,0,3)=="uid"?1:0):-1;
  22.             uid=substr($12,match($12,/\=[^\-]+/)+1,RLENGTH-1);
  23.             for(i=1;i<=11;i++) printf("%s"FS,$i);
  24.             printf("%d\t%s"RS,isNew,uid!=0?uid:"x"); #1 new,0 old,-1 hanving no "-"
  25.         }
  26. }' errFile=$errFile | \
  27. #sort -t \t -k 13 |sort -t \t -u | awk 'BEGIN{FS="\t";}{print $13" "NR;}';
  28. #awk 'BEGIN{FS="\t";}{ print $13" "NR;}';
  29. awk 'BEGIN{FS="\t";}{print $13}';
  30. end=`date +%s%N`;
  31. /bin/echo 'runTime(s):'`expr $end - $start | awk '{while(length($0)<10) $0=0$0;print $0}' | sed 's/\([0-9]*\)\([0-9]\{9\}\)$/\1\.\2/'`
  32. /bin/echo 'errData:'`wc -l $errFile`;
  33. exit $?;

1-6行,确定参数文件类型及其个数,如果不是文件,不是一个参数,exit 1,返回错误,并将错误输出到终端

7-10,分别是设置开始运行时间,错误日志存储文件,捕获第一个参数,输出等待

11-12,12为11的精简,说是精简其实11是找到以ip开始的字段,如果不是ip开始的直接忽略掉,不读取,而12是默认所有字段都读取,同样是默认了日志中不会存在异常数据!功能有两个:1,ip, (ip逗号空格)替换成ip,(ip逗号),
2,形如[30/Oct/2011:00:11:45 +0800]格式的字段 替换成 [30-Oct-2011:00:11:45],这里说为什么不替换成[30-Oct-2011 00:11:45],因为下面我们要把空格替换成\t所以这里必须当成一个字符来使用,以确定不被替换,下面使用的时候可以直接删除再使用!

13,替换空格为\t

14-26,其中16行输出异常数据行号,并终止循环!17行将错误数据输出到$errFile,并用到了awk中使用shell变量方法,21-22截取得到uid和"-" 并判断"-"的位置,"-"在前面为1,后面为0,23行,输出$1-$11的值,并以FS结尾(FS="\t"),24行,将得到的uid和对"-"的判断输出,中间用fs隔开,结尾用NR(NR="\n"),shell传递变量给awk

27,27行使用管道隔开了三段程序,第一段以\t为分隔符,以$13为标准排序,第二段以\t为分隔符删除重复数据,第三段输出13和本行的行号.由于这一段是注释掉的,所以程序运行时默认空格!

28-29同27行第三段!

31-33,分别是算出时间差,算出错误数据,返回$?(如果运行正确,$?=0).

上面这段程序仅是处理的一小部分,还有日志的很多处理需要设定,以后再来编辑!

这里更改一下sort 对tab键的操作

sort -t $'\t' -k123 或 sort -t'      ' -k123  顶啊!!!!好不容易搜索出来的!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值