Chinaunix
标题:
如何用awk从日志文件中找到时间范围的数据
[打印本页]
作者:
fortunegzhou
时间:
2013-08-27 17:48
标题:
如何用awk从日志文件中找到时间范围的数据
本帖最后由 fortunegzhou 于 2013-08-28 14:34 编辑
日志格式如下
2013/08/16 01:10:11.111 E12345678900-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:11:22.222 E12345678900-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:12:33.046 E68C93001100-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:13:33.046 E68C93001100-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:14:33.046 E68C93001100-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:15:33.046 E68C93001100-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:16:11.111 E12345678900-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:17:22.222 E12345678900-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:18:33.046 E68C93001100-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:19:33.046 E68C93001100-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:20:33.046 E68C93001100-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:21:33.046 E68C93001100-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:22:11.111 E12345678900-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:25:22.222 E12345678900-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:30:33.046 E68C93001100-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:32:33.046 E68C93001100-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:36:33.046 E68C93001100-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:40:33.046 E68C93001100-0 6513 123 0 IN OK() 0 0 0 0 0 0
请问:如何用awk找到时间范围是2013/08/16 01:15:00.000 到 2013/08/16 01:30:00.000 之间的日志数据
另:日志文件很大,5G以上,用什么方式查会快??
----------------------------------------2013/08/28(上午)更新-------------------------------------------------------
感谢大家的帮助,现报告各种写法的速度情况:
测试文件:2G, 返回的结果集在文件的末尾,大概15条
awk '{t=$1$2; if(t>="2013/08/2001:15:00.000" && t<"2013/08/2001:20:00.000" print}' $filename
awk '$1$2 >= "2013/08/2001:15:00.000" && $1$2 <= "2013/08/2001:20:00.000"' $filename
awk -vs="2013/08/20 01:15:00.000" -ve="2013/08/20 01:20:00.000" '{t=$1" "$2}s<=t&&t<=e' $filename
awk 'BEGIN{s="2013/08/20 01:15:00.000";e="2013/08/20 01:20:00.000"}{t=$1" "$2}s<=t&&t<=e' $filename
这三种写法,执行速度最快,时间都在25s或26s
awk 'BEGIN{start=mktime("2013 08 20 01 15 00";end=mktime("2013 08 20 01 20 00"}{split($1" "$2,a,"[/|.| ]";now=mktime(a[1]" "a[2]" "a[3]" "a[4]" "a[5]" "a[6]);if(now>=start&&(now<end||(now==end&&a[7]==0))) print $0}' $filename
这种写法,速度很慢,至少5分钟没出结果,估计是mktime命令执行相当慢, 此种写法没问题,我测试过小文件,能返回正确结果
用perl脚本也比较慢,都超过200s
perl -lane 'BEGIN{$s="2013/08/20 01:15:00.000";$e="2013/08/20 01:20:00.000"}{$t="$F[0] $F[1]";if($s lt $t && $t lt $e){print}}' $filename
用时244s
perl -lane 'print if "2013/08/20 01:15:00.000" lt "@F[0..1]" and "@F[0..1]" lt "2013/08/20 01:20:00.000"' $filename
用时259s
”seesea2517“的方案:没出正确的结果,估计是\t分隔符所致,我的日志文件可能不是\t分隔的,但是不管怎样,命令执行完需耗时分别如下:
cat $filename | sed -n '/2013\/08\/20\t01:15/, /2013\/08\/20\t01:20/ p' 28s
cat $filename | sed -n '/2013\/08\/20\t01:15/, /2013\/08\/20\t01:20/ p; /2013\/08\/20\t01:20/q;' 46s
----------------------------------------2013/08/28(下午)更新-------------------------------------------------------
根据cao627的提议,我试了2楼Shell_HAT的grep方式,发现速度更快,只用了2s
grep -E "2013/08/20\s*01:1[5-9]" ./2G.log
作者:
Shell_HAT
时间:
2013-08-27 17:55
grep -E "2013/08/16 01:1[5-9]|2013/08/16 01:2[0-9]" a.log
复制代码
作者:
fortunegzhou
时间:
2013-08-27 18:01
回复
2#
Shell_HAT
awk如何实现?
作者:
guogang225
时间:
2013-08-27 18:05
本帖最后由 guogang225 于 2013-08-27 18:14 编辑
awk 'BEGIN{start=mktime("2013 08 16 01 15 00");end=mktime("2013 08 16 01 30 00")}{split($1" "$2,a,"[/|:|.| ]");now=mktime(a[1]" "a[2]" "a[3]" "a[4]" "a[5]" "a[6]);if(now>=start&&(now<end||(now==end&&a[7]==0))) print $0}' urfile
复制代码
回复
1#
fortunegzhou
作者:
关阴月飞
时间:
2013-08-27 18:11
回复
1#
fortunegzhou
awk '$1$2 >= "2013/08/1601:15:00.000" && $1$2 <= "2013/08/1601:30:00.000"' file
复制代码
作者:
jason680
时间:
2013-08-27 18:26
回复
3#
fortunegzhou
try them ...
# awk -vs="2013/08/16 01:15:00.000" -ve="2013/08/16 01:30:00.000" '{t=$1" "$2}s<t&&t<e' FILE
# awk 'BEGIN{s="2013/08/16 01:15:00.000";e="2013/08/16 01:30:00.000"}{t=$1" "$2}s<t&&t<e' FILE
# perl -lane 'BEGIN{$s="2013/08/16 01:15:00.000";$e="2013/08/16 01:30:00.000"}{$t="$F[0] $F[1]";if($s lt $t && $t lt $e){print}}' FILE
作者:
kernel69
时间:
2013-08-27 21:35
学习了perl 字符串的比较方法
按你的改了改
perl -lane 'print if "2013/08/16 01:15:00.000" lt "@F[0..1]" and "@F[0..1]" lt "2013/08/16 01:30:00.000"' filename
复制代码
回复
6#
jason680
作者:
Shell_HAT
时间:
2013-08-27 22:04
回复
3#
fortunegzhou
能否用你的数据测试一下这些方案,看看哪个最快,给大家分享一下吧
作者:
reyleon
时间:
2013-08-27 22:11
回复
5#
关阴月飞
这种比较是不是awk会忽略相关的字符自动转换为数字进行比较的?应该是这样吧
作者:
seesea2517
时间:
2013-08-28 09:49
建议上述用 awk 或 perl 的,可以在找到匹配的最后一行的时候执行退出执行,即后续不再扫描,对于大文件来说应该能提高速度。
如果lz允许一点容错的话,比如多了一两行数据没关系的话,sed的示例:
[seesea@UC ~]$ cat file | sed -n '/2013\/08\/16\t01:15/, /2013\/08\/16\t01:30/ p'
2013/08/16 01:15:33.046 E68C93001100-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:16:11.111 E12345678900-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:17:22.222 E12345678900-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:18:33.046 E68C93001100-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:19:33.046 E68C93001100-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:20:33.046 E68C93001100-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:21:33.046 E68C93001100-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:22:11.111 E12345678900-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:25:22.222 E12345678900-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:30:33.046 E68C93001100-0 6513 123 0 IN OK() 0 0 0 0 0 0
# 加上 q 命令,在找到最后一个匹配行退出,后续如果有几G的内容就能省下很多时间啦
[seesea@UC ~]$ cat file | sed -n '/2013\/08\/16\t01:15/, /2013\/08\/16\t01:30/ p; /2013\/08\/16\t01:30/q;'
2013/08/16 01:15:33.046 E68C93001100-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:16:11.111 E12345678900-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:17:22.222 E12345678900-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:18:33.046 E68C93001100-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:19:33.046 E68C93001100-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:20:33.046 E68C93001100-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:21:33.046 E68C93001100-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:22:11.111 E12345678900-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:25:22.222 E12345678900-0 6513 123 0 IN OK() 0 0 0 0 0 0
2013/08/16 01:30:33.046 E68C93001100-0 6513 123 0 IN OK() 0 0 0 0 0 0
复制代码
作者:
li0924
时间:
2013-08-28 10:27
awk -F"[: ]+" '{if($1=="2013/08/16" && $2=="01" && $3>=15 && $3<30) print}'
作者:
fortunegzhou
时间:
2013-08-28 10:41
感谢大家的帮助,现报告各种写法的速度情况:
测试文件:2G, 返回的结果集在文件的末尾,大概15条
awk '{t=$1$2; if(t>="2013/08/2001:15:00.000" && t<"2013/08/2001:20:00.000"
print}' $filename
awk '$1$2 >= "2013/08/2001:15:00.000" && $1$2 <= "2013/08/2001:20:00.000"' $filename
awk -vs="2013/08/20 01:15:00.000" -ve="2013/08/20 01:20:00.000" '{t=$1" "$2}s<=t&&t<=e' $filename
awk 'BEGIN{s="2013/08/20 01:15:00.000";e="2013/08/20 01:20:00.000"}{t=$1" "$2}s<=t&&t<=e' $filename
这三种写法,执行速度最快,时间都在25s或26s
awk 'BEGIN{start=mktime("2013 08 20 01 15 00"
;end=mktime("2013 08 20 01 20 00"
}{split($1" "$2,a,"[/|
.| ]"
;now=mktime(a[1]" "a[2]" "a[3]" "a[4]" "a[5]" "a[6]);if(now>=start&&(now<end||(now==end&&a[7]==0))) print $0}' $filename
这种写法,速度很慢,至少5分钟没出结果,估计是mktime命令执行相当慢, 此种写法没问题,我测试过小文件,能返回正确结果
用perl脚本也比较慢,都超过200s
perl -lane 'BEGIN{$s="2013/08/20 01:15:00.000";$e="2013/08/20 01:20:00.000"}{$t="$F[0] $F[1]";if($s lt $t && $t lt $e){print}}' $filename
用时244s
perl -lane 'print if "2013/08/20 01:15:00.000" lt "@F[0..1]" and "@F[0..1]" lt "2013/08/20 01:20:00.000"' $filename
用时259s
作者:
cao627
时间:
2013-08-28 11:37
@fortunegzhou
想看一下2楼grep的时间。
还有我觉得11楼命令的执行时间会比最快的3个命令时间会长一些。
如果是这样,正好说明一个问题,机器是以判断数而不是单个判断的人维复杂度决定程序执行时间。
作者:
rucypli
时间:
2013-08-28 12:02
awk -F. '{if($1>"2013/08/16 01:15:33" && $1<"2013/08/16 01:21:33")print $0}' filename
作者:
cao627
时间:
2013-08-28 12:39
cao627 发表于 2013-08-28 11:37
@fortunegzhou想看一下2楼grep的时间。
还有我觉得11楼命令的执行时间会比最快的3个命令时间会长一些。
如 ...
不过&&运算是短路操做的是,所以对于非2013/08/16 的数据,11楼命令的四次判断的后三次是不会执行的。
所以,如果文件中日期非2013/08/16的数据量远大于这个日期的数据量时,11楼似乎是有优势的。
想看看楼主贴出11漏命令的执行时间。
作者:
davidbeckham921
时间:
2013-08-28 13:18
本帖最后由 davidbeckham921 于 2013-08-28 13:22 编辑
猛!看起来很不错的样子。
不说perl效率更高吗?语法看样子都差不多,但是awk这回占得先机了。这是为什么呢?
作者:
fortunegzhou
时间:
2013-08-28 14:36
回复
13#
cao627
根据cao627的提议,我试了2楼Shell_HAT的grep方式,发现速度更快,只用了2s
grep -E "2013/08/20\s*01:1[5-9]" ./2G.log
作者:
chenkun1998
时间:
2013-10-15 11:44
本帖最后由 chenkun1998 于 2013-10-15 13:41 编辑
awk '$2>="01:15:00.000" && $2<="01:30:00.000" {print $0}' file
作者:
xjj571249
时间:
2014-12-24 00:47
非常感谢啊!搞了一个晚上,终于从你帖子中找到方法了,感谢@
作者:
goofool
时间:
2014-12-24 08:22
回复
1#
fortunegzhou
楼主试没试10楼的第种方法,我想知道这个效率怎么样,我感觉这个应该是最快的。
作者:
聆雨淋夜
时间:
2014-12-24 11:15
回复
9#
reyleon
我也不清楚,谁说说看
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2