我有一个包含时间序列事件的日志文件。现在,我想分析数据以计算不同间隔的事件数量。每个条目都表明在此时间戳中发生了事件。例如,这是日志文件的一部分
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
进行救援。
awk -v FS="" '{min=$5<5?0:5; a[$1$2$4min]++} END{for (i in a) print i, a[i]}' file
解释
它在每一行中获得了第一个,第二,第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
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.
用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
我意识到这是一个古老的问题,但是当我偶然发现它时,我无法抗拒从另一个方向戳戳它...
sed -e 's/:/ /' -e 's/[0-4]:.*$/0/' -e 's/[5-9]:.*$/5/' | uniq -c
在此形式中,它假定数据来自标准输入,或在管道之前添加文件名作为最终参数。
这与Michal的初始方法没有什么不同,但是如果您碰巧需要对巨大日志进行快速肮脏的分析,那么SED是一种轻巧且功能强大的工具。
假设数据确实以常规格式 - 任何打ic出现在结果中。
作为分解 - 给定输入
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作为前端的最大优势是您可以在远程记录的情况下选择感兴趣的线:
sed -e '/sshd.*: Accepted .* for root from/!d' -e 's/:/ /' ... /var/log/secure