我有一个这样的日志:
DEBUG: Worker thread (#12) initialized
DEBUG: Worker thread (#19) initialized
DEBUG: Worker thread (#9) initialized
DEBUG: Worker thread (#15) initialized
DEBUG: Worker thread (#3) initialized
DEBUG: Worker thread (#17) initialized
DEBUG: Worker thread (#14) initialized
DEBUG: Worker thread (#16) initialized
Threads started!
[ 5s ] thds: 20 tps: 35265.85 qps: 35265.85 (r/w/o: 0.00/35265.85/0.00) lat (ms,99%): 2.52 err/s: 0.00 reconn/s: 0.00
[ 10s ] thds: 20 tps: 35965.67 qps: 35965.67 (r/w/o: 0.00/35965.67/0.00) lat (ms,99%): 2.03 err/s: 0.00 reconn/s: 0.00
...
我想解析这个日志文件并获取以下所有行:
[ 5s ] thds: 20 tps: 35265.85 qps: 35265.85 (r/w/o: 0.00/35265.85/0.00) lat (ms,99%): 2.52 err/s: 0.00 reconn/s: 0.00
[ 10s ] thds: 20 tps: 35965.67 qps: 35965.67 (r/w/o: 0.00/35965.67/0.00) lat (ms,99%): 2.03 err/s: 0.00 reconn/s: 0.00
....
然后我想将这些线条转换成以下格式进行绘图:
5,35265.85
10,35965.67
...
这是我的 awk 代码:
#!/usr/bin/env bash
awk '
BEGIN {
printf "#time,tps\n";
}
/^\[\ [0-9]{1,4}[s]?\ \]/ { # regex for [ 1050s ]
printf "%s,%s\n", substr($2,1, length($2)-1), $7
}
' "$@"
我不喜欢这个解决方案的一点是:我必须手动计算 awk 生成的标记索引。我更喜欢更好的解决方案,例如:“字符串“tps”之后的第一个标记”。这样,它会更通用,更容易解析。
我的问题是:我真的可以使用 awk 来做到这一点吗?还是有更好的解决方案来处理我的情况?
最佳答案
这是执行此操作的一种方法。假设您的日志文件名为 data.txt
.您可以运行以下命令
cat data.txt | grep -wE "5s|10s" | awk '{print substr($(NF-16), 1, length($(NF-16))-1) "," $(NF-13) "," $(NF-11) "," $(NF-9)}'
说明
-
cat <filename>
将文件内容打印到标准输出 -
grep -wE <exp>
过滤 cat 的输出并选择包含表达式的行,在我们的例子中是5s or 10s
.-w
确保只选择与整个单词匹配的行或5s
没有-w
也选择15s, 20s ..
等等,
这将选择以下行 awk
正在运行
[ 5s ] thds: 20 tps: 35265.85 qps: 35265.85 (r/w/o: 0.00/35265.85/0.00) lat (ms,99%): 2.52 err/s: 0.00 reconn/s: 0.00
[ 10s ] thds: 20 tps: 35965.67 qps: 35965.67 (r/w/o: 0.00/35965.67/0.00) lat (ms,99%): 2.03 err/s: 0.00 reconn/s: 0.00
- 使用
awk
我们可以使用NF
找出每行中的字段数awk '{print NF}'
即 18
提取相应的内容在NF-16
, NF-13
, NF-11
和 NF-9
第 位置。即分别为第 2、5、7 和 9 位。但是,第二个位置是 5s|10s
等等,你想删除尾部 s
这可以通过 substr($2, 1, length($2)-1)
来完成即从第一个字符到 5s/10s 的长度,即相应的 2/3 并使用 -1
删除最后一个字符.
你的最终命令是
awk '{print substr($(NF-16), 1, length($(NF-16))-1) "," $(NF-13) "," $(NF-11) "," $(NF-9)}'
可以替换为
awk '{print substr($2, 1, length($2)-1)","$5","$7","$9}'
把所有的东西放在一起
cat data.txt | grep -wE "5s|10s" | awk '{print substr($2, 1, length($2)-1)","$5","$7","$9}'
关于linux - 使用awk解析转换如下日志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56928584/