AWK - 是否可以按不同的字段 && 按小时细分日志文件
AWK - Is it possible to Breakdown a log file by a distinct field && by hour
问题
I am trying to find out if it is possible with awk
alone to pass in
a log file and then have awk
output a distinct message with a
breakdown of the hour (00-23) as well as a count, for that particular
hour vs distinct message.
例子
请求输出
Message1
00 13
01 30
...
23 6
Message2
00 50
01 10
...
23 120
etc, etc
输入文件看起来有点像下面这样:
blah,blah
2016-06-24 00:30:54 blah Message1 7 rand rand2
2016-06-24 00:40:12 blah Message2 35 rand rand2
2016-06-24 00:42:15 blah Message2 12 rand rand2
2016-06-24 00:58:01 blah Message1 5 rand rand2
2016-06-24 00:58:12 blah Message2 3 rand rand2
2016-06-24 01:02:25 blah Message2 2 rand rand2
2016-06-24 01:02:30 blah Message1 3 rand rand2
2016-06-24 01:05:14 blah Message1 10 rand rand2
2016-06-24 01:30:56 blah Message2 5 rand rand2
2016-06-24 01:55:41 blah Message2 3 rand rand2
blah, blah
请注意,这是一个编造的输入文件。
要从该输入文件中获取请求的输出,我知道我需要 print
然后在新的一行上执行类似 print substr(,1,2)" "sum[]
的操作。对于相同 </code> 的相同时间,我将不得不将 <code>
加在一起。
代码
另请注意,我必须使用 awk
3.1.7,所以我无法使用 awk
4.1.0+.
我知道如何获取不同的消息。
{
msg[]++
}
END {
for (m in msg) {
print m;
}
}
到 return 小时,我可以按照以下方式做一些事情:
{
msg[]++
hr[] = substr(,1,2)
}
END {
for (m in msg) {
print m;
print hr[m];
}
}
最后的总和是:
{
msg[]++
hr[] = substr(,1,2)
sum[] +=
}
END {
for (m in msg) {
print m;
print hr[m]" "sum[m];
}
}
非常感谢任何帮助。
你会想要这样的东西:
$ cat tst.awk
BEGIN { FS="[ :]" }
{ sum[,]+=; msgs[]; hrs[] }
END {
for (msg in msgs) {
print msg
for (hr in hrs) {
print hr, sum[msg,hr]+0
}
print ""
}
}
$ awk -f tst.awk file
Message1
00 12
01 13
Message2
00 50
01 10
但显然这有点猜测,因为它 运行 与您发布的示例输入不同,但您没有提供相关的预期输出。
顺便说一句,关于问题的主题行 AWK - Is it possible...
,假设它是关于操纵文本的,那么该问题的答案总是 "yes",所以无需询问是否可行。
我刚刚注意到你之前的问题,你说小时可能并不总是出现在你的数据中,所以这可能是你真正想要的:
$ cat tst.awk
BEGIN { FS="[ :]" }
{ sum[,+0]+=; msgs[] }
END {
for (msg in msgs) {
print msg
#for (hr=0; hr<=23; hr++) {
for (hr=0; hr<=4; hr++) {
printf "%02d %d\n", hr, sum[msg,hr]
}
print ""
}
}
$
$ awk -f tst.awk file
Message1
00 12
01 13
02 0
03 0
04 0
Message2
00 50
01 10
02 0
03 0
04 0
明显把“4”改成“23”。我还建议您考虑使用 CSV 输出,这样您就可以导入到 Excel 等,例如:
$ cat tst.awk
BEGIN { FS="[ :]"; OFS="," }
{ sum[,+0]+=; msgs[] }
END {
printf "hr"
for (msg in msgs) {
printf "%s%s", OFS, msg
}
print ""
for (hr=0; hr<=4; hr++) {
printf "%02d", hr
for (msg in msgs) {
printf "%s%d", OFS, sum[msg,hr]
}
print ""
}
}
$ awk -f tst.awk file
hr,Message1,Message2
00,12,50
01,13,10
02,0,0
03,0,0
04,0,0
$ awk -f tst.awk file | column -s, -t
hr Message1 Message2
00 12 50
01 13 10
02 0 0
03 0 0
04 0 0
问题
I am trying to find out if it is possible with
awk
alone to pass in a log file and then haveawk
output a distinct message with a breakdown of the hour (00-23) as well as a count, for that particular hour vs distinct message.
例子
请求输出
Message1
00 13
01 30
...
23 6
Message2
00 50
01 10
...
23 120
etc, etc
输入文件看起来有点像下面这样:
blah,blah
2016-06-24 00:30:54 blah Message1 7 rand rand2
2016-06-24 00:40:12 blah Message2 35 rand rand2
2016-06-24 00:42:15 blah Message2 12 rand rand2
2016-06-24 00:58:01 blah Message1 5 rand rand2
2016-06-24 00:58:12 blah Message2 3 rand rand2
2016-06-24 01:02:25 blah Message2 2 rand rand2
2016-06-24 01:02:30 blah Message1 3 rand rand2
2016-06-24 01:05:14 blah Message1 10 rand rand2
2016-06-24 01:30:56 blah Message2 5 rand rand2
2016-06-24 01:55:41 blah Message2 3 rand rand2
blah, blah
请注意,这是一个编造的输入文件。
要从该输入文件中获取请求的输出,我知道我需要 print
然后在新的一行上执行类似 print substr(,1,2)" "sum[]
的操作。对于相同 </code> 的相同时间,我将不得不将 <code>
加在一起。
代码
另请注意,我必须使用 awk
3.1.7,所以我无法使用 awk
4.1.0+.
我知道如何获取不同的消息。
{
msg[]++
}
END {
for (m in msg) {
print m;
}
}
到 return 小时,我可以按照以下方式做一些事情:
{
msg[]++
hr[] = substr(,1,2)
}
END {
for (m in msg) {
print m;
print hr[m];
}
}
最后的总和是:
{
msg[]++
hr[] = substr(,1,2)
sum[] +=
}
END {
for (m in msg) {
print m;
print hr[m]" "sum[m];
}
}
非常感谢任何帮助。
你会想要这样的东西:
$ cat tst.awk
BEGIN { FS="[ :]" }
{ sum[,]+=; msgs[]; hrs[] }
END {
for (msg in msgs) {
print msg
for (hr in hrs) {
print hr, sum[msg,hr]+0
}
print ""
}
}
$ awk -f tst.awk file
Message1
00 12
01 13
Message2
00 50
01 10
但显然这有点猜测,因为它 运行 与您发布的示例输入不同,但您没有提供相关的预期输出。
顺便说一句,关于问题的主题行 AWK - Is it possible...
,假设它是关于操纵文本的,那么该问题的答案总是 "yes",所以无需询问是否可行。
我刚刚注意到你之前的问题,你说小时可能并不总是出现在你的数据中,所以这可能是你真正想要的:
$ cat tst.awk
BEGIN { FS="[ :]" }
{ sum[,+0]+=; msgs[] }
END {
for (msg in msgs) {
print msg
#for (hr=0; hr<=23; hr++) {
for (hr=0; hr<=4; hr++) {
printf "%02d %d\n", hr, sum[msg,hr]
}
print ""
}
}
$
$ awk -f tst.awk file
Message1
00 12
01 13
02 0
03 0
04 0
Message2
00 50
01 10
02 0
03 0
04 0
明显把“4”改成“23”。我还建议您考虑使用 CSV 输出,这样您就可以导入到 Excel 等,例如:
$ cat tst.awk
BEGIN { FS="[ :]"; OFS="," }
{ sum[,+0]+=; msgs[] }
END {
printf "hr"
for (msg in msgs) {
printf "%s%s", OFS, msg
}
print ""
for (hr=0; hr<=4; hr++) {
printf "%02d", hr
for (msg in msgs) {
printf "%s%d", OFS, sum[msg,hr]
}
print ""
}
}
$ awk -f tst.awk file
hr,Message1,Message2
00,12,50
01,13,10
02,0,0
03,0,0
04,0,0
$ awk -f tst.awk file | column -s, -t
hr Message1 Message2
00 12 50
01 13 10
02 0 0
03 0 0
04 0 0