因为刚接触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-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
顶啊!!!!好不容易搜索出来的!
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对这段文字的处理
- #!/bin/sh
- if [ $# -ne 1 ] || [ ! -f $1 ]
- then
-
echo 'Warnning:"Incorrect number of parameters setted only one and must be a file type"' >&2; -
exit 1; - fi;
- start=`date +%s%N`;
- errFile='./lag.txt';#error data file
- file=$1;
- /bin/echo 'Script running! please wait ....' 1>&2;
- #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 | \
- 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 | \
- awk 'BEGIN{FS="\"";}{for(i=1;i<=NF;i++){if(i%2==1) gsub(" ","\t",$i);printf "%s",$i (i==NF?RS:FS);}}'| \
- awk 'BEGIN{n=0;FS="\t";}{
-
#Check the regular expression is correct or not -
if($11!="->"){print $0;print NR;exit;} -
if($12=="--"){#redirect to ./lag.txt file -
gsub("\t"," ",$0); -
print $0" "NR> errFile; -
}else{ -
isNew = $12~/-/?(substr($12,0,3)=="uid"?1:0):-1; -
uid=substr($12,match($12,/\=[^\-]+/)+1,RLENGTH-1); -
for(i=1;i<=11;i++) printf("%s"FS,$i); -
printf("%d\t%s"RS,isNew,uid!=0?uid:"x"); #1 new,0 old,-1 hanving no "-" -
} - }' errFile=$errFile | \
- #sort -t \t -k 13 |sort -t \t -u | awk 'BEGIN{FS="\t";}{print $13" "NR;}';
- #awk 'BEGIN{FS="\t";}{ print $13" "NR;}';
- awk 'BEGIN{FS="\t";}{print $13}';
- end=`date +%s%N`;
- /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/'`
- /bin/echo 'errData:'`wc -l $errFile`;
- 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'