我有一个包含时间序列事件的日志文件。现在,我想分析数据以计算不同时间间隔的事件数。每个条目都显示在此时间戳中发生了一个事件。例如,这是日志文件的一部分
09:00:00
09:00:35
09:01:20
09:02:51
09:03:04
09:05:12
09:06:08
09:06:46
09:07:42
09:08:55
我需要以5分钟的间隔计算事件。结果应该是:
09:00 4 //which means 4 events from time 09:00:00 until 09:04:59<br>
09:05 5 //which means 4 events from time 09:00:05 until 09:09:59<br>
等等。
你知道bash,shell,awk,......中的任何技巧吗? 任何帮助表示赞赏。
答案 0 :(得分:1)
awk
救援。
awk -v FS="" '{min=$5<5?0:5; a[$1$2$4min]++} END{for (i in a) print i, a[i]}' file
它获取每行中第1个,第2个,第4个和第5个字符的值,并跟踪它们出现的次数。要在0-4
和5-9
范围内进行分组,它会创建var min
,在第一种情况下为0
,在第二种情况下为5
。
根据您的输入,
$ awk -v FS="" '{min=$5<5?0:5; a[$1$2$4min]++} END{for (i in a) print i, a[i]}' a
0900 5
0905 5
使用另一个示例输入
$ cat a
09:00:00
09:00:35
09:01:20
09:02:51
09:03:04
09:05:12
09:06:08
09:06:46
09:07:42
09:08:55
09:18:55
09:19:55
10:09:55
10:19:55
$ awk -v FS="" '{min=$5<5?0:5; a[$1$2$4min]++} END{for (i in a) print i, a[i]}' a
0900 5
0905 5
0915 2
1005 1
1015 1
答案 1 :(得分:0)
使用awk的另一种方式
awk -F : '{t=sprintf ("%02d",int($2/5)*5);a[$1 FS t]++}END{for (i in a) print i,a[i]}' file |sort -t: -k1n -k2n
09:00 5
09:05 5
说明:
use : as field seperator
int($2/5)*5 is used to group the minutes into every 5 minute (00,05,10,15...)
a[$1 FS t]++ count the numbers.
the last sort command will output the sorted time.
答案 2 :(得分:0)
Perl,输出通过uniq
传输,只是为了好玩:
$ cat file
09:00:00
09:00:35
09:01:20
09:02:51
09:03:04
09:05:12
09:06:08
09:06:46
09:07:42
09:08:55
09:18:55
09:19:55
10:09:55
10:19:55
11:21:00
命令:
perl -F: -lane 'print $F[0].sprintf(":%02d",int($F[1]/5)*5);' file | uniq -c
输出:
5 09:00
5 09:05
2 09:15
1 10:05
1 10:15
1 11:20
1 11:00
或者只是perl:
perl -F: -lane '$t=$F[0].sprintf(":%02d",int($F[1]/5)*5); $c{$t}++; END { print join(" ", $_, $c{$_}) for sort keys %c }' file
输出:
09:00 5
09:05 5
09:15 2
10:05 1
10:15 1
11:00 1
11:20 1
答案 3 :(得分:0)
我意识到这是一个古老的问题,但当我偶然发现它时,我无法抗拒从另一个方向向它戳戳......
sed -e 's/:/ /' -e 's/[0-4]:.*$/0/' -e 's/[5-9]:.*$/5/' | uniq -c
在此表单中,它假设数据来自标准输入,或者将文件名添加为管道之前的最终参数。
这与Michal的初始方法没有什么不同,但如果您碰巧需要对大型日志进行快速而肮脏的分析,那么sed是一种轻量级且功能强大的工具。
假设数据确实是常规格式 - 任何打嗝都会出现在结果中。
作为细分 - 给出输入
09:00:35
09:01:20
09:02:51
09:03:04
09:05:12
09:06:08
并单独应用每个编辑子句,中间结果如下: 1)消除第一个结肠。
-e 's/:/ /'
09 00:35
09 01:20
09 02:51
09 03:04
09 05:12
2)将分钟0到4转换为0。
-e 's/[0-4]:.*$/0/'
09 00
09 00
09 00
09 00
09 05:12
09 06:08
3)将分钟5-9转换为5:
-e 's/[5-9]:.*$/5/'
09 00
09 00
09 00
09 00
09 05
09 05
2和3也会删除行中的所有尾随内容,这会使行不唯一(因此'uniq -c'将无法产生所需的结果)。
使用sed作为前端的最大优势可能是您可以选择感兴趣的行,例如,如果root远程登录:
sed -e '/sshd.*: Accepted .* for root from/!d' -e 's/:/ /' ... /var/log/secure