Bash 排序不正确按时间排序

Bash sort not sorting by time correctly

我正在尝试对日志进行排序以显示攻击服务器的前 3 个唯一 IP 地址。我整理日志以查找失败的密码尝试。然后我根据日期对该输出进行排序。然后,我根据第 11 列将该输出通过管道传输到另一种排序,以便仅获取每个唯一 IP 地址第一次出现的攻击。我将输出通过管道传递给 head 函数以获取前 3 行,然后使用 awk 将它们打印出来。我使用的命令是:grep 'Failed password' auth.log | sort -k1M -nk2 -nk3 | sort -k11,11 -u | head -3 | awk '{print " "" "" "}'

从此代码中提取了正确的 IP 地址,但它们基于时间的顺序是乱序的,如下所示:

我曾尝试使用 -nk3.1,3.2 -nk3.4,3.5 -nk3.7,3.8 而不是 -nk3,但我得到了相同的结果。 关于如何解决此问题的任何想法?

以下是日志文件的片段供您参考:

Oct 11 10:12:24 myraptor sshd[29463]: Connection from 169.139.243.218 port 57273
Oct 11 10:12:25 myraptor sshd[29465]: Failed password for harvey from 169.139.243.218 port 57273 ssh2
Oct 11 10:12:25 myraptor sshd[29467]: Received disconnect from 169.139.243.218: Bye Bye
Oct 11 10:12:27 myraptor sshd[29469]: Connection from 169.139.243.218 port 57274
Oct 11 10:12:28 myraptor sshd[29471]: Failed password for harvey from 169.139.243.218 port 57274 ssh2
Oct 11 10:12:28 myraptor sshd[29473]: Failed password for harvey from 169.139.243.218 port 57274 ssh2
Oct 11 10:12:28 myraptor sshd[29475]: Received disconnect from 169.139.243.218: 11: Bye Bye
Oct 11 10:13:03 myraptor sshd[29477]: Connection from 56.13.188.38 port 55319
Oct 11 10:13:04 myraptor sshd[29479]: Failed password for harvey from 56.13.188.38 port 55319 ssh2
Oct 11 10:13:04 myraptor sshd[29481]: Received disconnect from 56.13.188.38: Bye Bye
Oct 11 10:13:15 myraptor sshd[29483]: Connection from 30.167.206.91 port 55320
Oct 11 10:13:16 myraptor sshd[29485]: Failed password for harvey from 30.167.206.91 port 55320 ssh2
Oct 11 10:13:16 myraptor sshd[29487]: Received disconnect from 30.167.206.91: Bye Bye
Oct 11 10:13:18 myraptor sshd[29489]: Connection from 30.167.206.91 port 55321
Oct 11 10:13:18 myraptor sshd[29491]: Failed password for harvey from 30.167.206.91 port 55321 ssh2
Oct 11 10:13:18 myraptor sshd[29493]: Received disconnect from 30.167.206.91: Bye Bye

预期输出:

Oct 11 10:12:25 169.139.243.218
Oct 11 10:13:04 56.13.188.38
Oct 11 10:13:16 30.167.206.91

可以使用awk逐行统计IP地址

 grep 'Failed password' auth.log | sort -k1M -nk2 -nk3 | sort -k11,11 | awk '!d[]++' | head -3 | awk '{print " "" "" "}' 

请您尝试以下操作:

grep 'Failed password' auth.log | sort -k1M -nk2 -nk3 | awk '!seen[]++ {print , , , }' | head -n3

输出:

Oct 11 10:12:25 169.139.243.218
Oct 11 10:13:04 56.13.188.38
Oct 11 10:13:16 30.167.206.91

awk 条件 !seen[]++ 在不改变时间顺序的情况下统一第 11 个字段的外观。

在 awk 中:

$ awk '                    # all awk
=="Failed" {             # when Failed met
    if(!( in ips)) {    # and the ip has not been seen before
        ipc[++i]=       # increase stored ip counter
        ips[]           # and store ip for checking
        if(i==3)           # once we have 3 ips 
            exit           # we exit ie. execute END
    }
}
END {
    for(j=1;j<=i;j++)      # iterate index for ipc
        print ipc[j]       # and output
}' file

输出:

169.139.243.218
56.13.188.38
30.167.206.91

如果您仍然使用 awk,grep 就没用了。如果您使用的是 GNU awk,在大多数情况下您也可以跳过 sort