首页 > 解决方案 > 解析顶级日志数据

问题描述

我正在尝试解析收集的一系列顶级日志。解析完原文件后,我当前的文件是这样的:

#TIMESTAMP 1524703273 : 04/25/2018 08:41:13 PM
Cpu(s): 33.9%us,  4.5%sy,  0.0%ni, 60.2%id,  0.0%wa,  0.2%hi,  1.2%si,  0.0%st
#TIMESTAMP 1524703332 : 04/25/2018 08:42:12 PM
Cpu(s): 17.0%us,  2.1%sy,  0.0%ni, 80.7%id,  0.0%wa,  0.1%hi,  0.1%si,  0.0%st
#TIMESTAMP 1524703392 : 04/25/2018 08:43:12 PM
Cpu(s): 16.1%us,  2.7%sy,  0.0%ni, 80.8%id,  0.0%wa,  0.1%hi,  0.3%si,  0.0%st

我只希望“纪元时间戳(第二列(即)#TIMESTAMP 之后的字段),然后是下一行中的 %id 在同一行中”,我希望解析后的输出是这样的(时间戳和%id 将始终在替代行中,我希望它在同一行中)。

1524703273 60.2
1524703332 80.7
1524703392 80.8

目前,我正在使用一系列“剪切”命令并使用多个输出文件来实现这一点,有没有更好的方法来一次尝试实现这一点。

cut -d' ' -f 2,7 sample.txt > sample1.txt
cut -d' ' -f 2 sample1.txt > sample2.txt
cut -d'%' -f 1 sample2.txt > sample3.txt

然后sed 'N;s/\n/ /' sample3.txt合并每两行。

如果可能的话,如果我可以从 100 中减去第二个值并将其保存在同一个文件中,那就太好了。

1524703273 39.8 --> (100-60.2)
1524703332 19.3 --> (100-80.7)
1524703392 19.2 --> (100-80.8) 

标签: bashshellscripting

解决方案


第一个问题

尝试:

$ awk '/TIMESTAMP/{ts=$2; getline; print ts, $5+0}' logfile
1524703273 60.2
1524703332 80.7
1524703392 80.8

这个怎么运作:

  • /TIMESTAMP/{...}

    这将选择包含TIMESTAMP和对于这些行的行,并且只有那些行,花括号中的命令才会被执行。这些命令是:

  • ts=$2

    这会将时间戳值保存在变量中ts

  • getline

    这在下一行中读取。

  • print ts, $5+0

    这将打印时间戳值 , ts,然后是我们刚刚读取的行的第五列。通过向第五列中的值添加零,我们强制 awk 将其转换为数字,从而消除不需要的字符%id

第二个问题

从字面上获取您想要的输出:

$ awk '/TIMESTAMP/{ts=$2; getline; id=$5+0; printf "%s %s --> (100-%s)\n",ts,100-id,id}' logfile
1524703273 39.8 --> (100-60.2)
1524703332 19.3 --> (100-80.7)
1524703392 19.2 --> (100-80.8)

或者,也许你真正想要的是:

$ awk '/TIMESTAMP/{ts=$2; getline; id=$5+0; print ts, id, 100-id}' logfile
1524703273 60.2 39.8
1524703332 80.7 19.3
1524703392 80.8 19.2

或者可能:

$ awk '/TIMESTAMP/{ts=$2; getline; id=$5+0; print ts, 100-id}' logfile
1524703273 39.8
1524703332 19.3
1524703392 19.2

推荐阅读