regex - 使用 bash 和 awk 将日志文件分组

标签 regex bash shell sorting awk

我正在尝试以特定方式对日志文件进行排序,但我不确定如何执行最后一步。

我的日志文件有这样的条目:

Feb 15 17:00:34 server sshd[13879]: Invalid user test from 200.242.94.133
Feb 15 17:00:35 server sshd[13780]: Invalid user ftpuser from 200.242.94.133
Feb 15 17:01:34 server sshd[13890]: Invalid user test from 200.242.94.133
Feb 15 17:01:35 server sshd[13791]: Invalid user vnc from 200.242.94.133
Feb 15 17:01:35 server sshd[13794]: Invalid user test from 50.63.172.108
Feb 15 17:01:36 server sshd[13798]: Invalid user vnc from 50.63.172.108

我使用命令:

cat logfile | grep "Invalid user" | awk '{print $8 ", " $10 }' | sort -t":" -k2,2 | uniq -c

哪些输出:

 1 ftpuser, 200.242.94.133
 2 test, 200.242.94.133
 1 test, 50.63.172.108 
 1 vnc, 200.242.94.133
 1 vnc, 50.63.172.108

我想得到:

1 ftpuser, (1) 200.242.94.133
3 test, (2) 200.242.94.133, (1) 50.63.172.108
2 vnc, (1) 200.242.94.133, (1) 50.63.172.108

我不确定如何对单词列进行求和,同时将 IP 地址单独计数,然后将其与其他结果一起包含在内。

尝试回答:

# awk '/Invalid user/{user[$8]++;ip[$8][$10]++} END{for (u in user){printf "%s %s",user[u],u;for (i in ip[u])printf ", (%s) %s",ip[u][i],i;print""}}' logfile | sort -k2
awk: /Invalid user/{user[$8]++;ip[$8][$10]++} END{for (u in user){printf "%s %s",user[u],u;for (i in ip[u])printf ", (%s) %s",ip[u][i],i;print""}}
awk:                                 ^ syntax error
awk: /Invalid user/{user[$8]++;ip[$8][$10]++} END{for (u in user){printf "%s %s",user[u],u;for (i in ip[u])printf ", (%s) %s",ip[u][i],i;print""}}
awk:                                                                                                   ^ syntax error
awk: /Invalid user/{user[$8]++;ip[$8][$10]++} END{for (u in user){printf "%s %s",user[u],u;for (i in ip[u])printf ", (%s) %s",ip[u][i],i;print""}}
awk:                                                                                                                               ^ syntax error

最佳答案

$ awk '/Invalid user/{user[$8]++;ip[$8][$10]++} END{for (u in user){printf "%s %s",user[u],u;for (i in ip[u])printf ", (%s) %s",ip[u][i],i;print""}}' logfile
2 vnc, (1) 50.63.172.108, (1) 200.242.94.133
1 ftpuser, (1) 200.242.94.133
3 test, (1) 50.63.172.108, (2) 200.242.94.133

如果您希望按用户字母顺序排序:

$ awk '/Invalid user/{user[$8]++;ip[$8][$10]++} END{for (u in user){printf "%s %s",user[u],u;for (i in ip[u])printf ", (%s) %s",ip[u][i],i;print""}}' logfile | sort -k2
1 ftpuser, (1) 200.242.94.133
3 test, (1) 50.63.172.108, (2) 200.242.94.133
2 vnc, (1) 50.63.172.108, (1) 200.242.94.133

上面的代码适用于 GNU awk。我还没有测试过 BSD。

它是如何工作的

  • /无效用户/{user[$8]++;ip[$8][$10]++}

    对于 日志文件 中包含无效用户的任何行,系统会计算用户名(字段 8)和 IP 地址(字段 10)。

  • END{for (u in user){printf "%s %s",user[u],u;for (i in ip[u])printf ", (%s) % s",ip[u][i],i;打印""}}

    当我们读完日志文件后,它会循环遍历我们见过的每个用户,并打印我们见过该用户的次数,后面是该用户的名字,最后是每个用户的名字IP 地址,该 IP 的计数,后跟该 IP。

关于regex - 使用 bash 和 awk 将日志文件分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28598043/

相关文章:

linux - ksh -x 带目录名

javascript - RegExp 用于匹配字符串开头的协议(protocol)相对 URL

bash - 为什么我的脚本的输出是 "mv: command not found"而当我直接在 shell 上运行它时却不是?

bash - grep 特定字符串并用 sed 替换该文件

linux - 吉拉命令行界面 : Viewing currently configured workflow --steps

shell - 检查HDFS文件是否已压缩的命令

javascript - 以任何顺序匹配查询中所有单词的正则表达式

javascript - 如何在已知的 XML 标签之间进行匹配?

python - 从字符串中删除具有某些约束的单词

Linux Shell 脚本已执行但未返回命令提示符