好记性不如烂笔头,mark一下:)
场景:
1. 日志目录中,每200M会压缩日志文件
日志文件:auth.log.2021081201.1.gz
2. 需要过滤所有压缩日志文件,过滤如下结构行,提取出username,并去重
2021-08-13 10:13:30.898 [WARN ] [http-nio-8180-exec-13] - clientid:d-1-11654987987987, username:11654987987987, token:ohSQE2b4J49fpW12, not found
2021-08-13 10:13:30.898 [WARN ] [http-nio-8180-exec-13] - clientid:d-1-99654987987987, username:99654987987987, token:ohSQE2b4J49fpW36, not found
可以看出,打印日志结构为:
*** clientid:{}, username:{}, token:{}, not found
操作:
1. 提取username,并写入到指定文件username.log
gzip -dc ./*.gz | grep "not found" | awk '{for(i=1; i<=NF; i++) { if (index($i, "username") > 0) { split($i, array, /[:,]/); print array[2]; }}}' >>username
=》分开解析
gzip -dc ./*.gz d 解压缩 c 输出到标准输出流
grep "not found" 过滤需要的行
awk '{ 默认使用空格作为每行内容的字段分隔符
for(i=1; i<=NF; i++) { NF是awk的内建数据变量,表示该行分割后字段个数
if (index($i, "username") > 0) { 遍历每个字段,是否包含username
split($i, array, /[:,]/); 对 username:***, 分割,分割符为 : 或 ,
print array[2]; 第1个为username,第2个为***,也去掉了末尾,
}
}
}' >>username.log 标准输出重定向到本地文件username
注意:index、split都是awk编程语言提供的字符串函数
index 没有找到返回0
split 分割字符串,split($i, array, ":") 使用:来分割
大概有30个压缩文件,压缩前200M,压缩后20M以内;
在8核32G虚机上执行时,使用top查看,CPU占用率能达到300%,不过很快就能执行完成吧
2. 对username.log去重,得到username-uniq.log
sort -su username.log > username-uniq.log 使用稳定排序,然后去重
在8核32G虚机上执行时,使用top查看,CPU占用率更高,也是很快就结束了
TODO 更高效的方法