根据日期/时间仅打印最后出现在日志文件中的唯一行

use*_*029 4 grep sed awk text-processing

我正在使用以下格式的日志文件:

Oct 12 01:28:26 server program: 192.168.1.105 text for 1.105 
Oct 12 01:30:00 server program: 192.168.1.104 text for 1.104 
Oct 12 01:30:23 server program: 192.168.1.103 text for 1.103
Oct 12 01:32:39 server program: 192.168.1.101 text for 1.101 
Oct 12 02:28:26 server program: 192.168.1.105 text for 1.105 
Oct 12 02:30:00 server program: 192.168.1.104 text for 1.104
Oct 12 02:30:23 server program: 192.168.1.103 text for 1.103 
Oct 12 02:32:39 server program: 192.168.1.101 text for 1.101 
Run Code Online (Sandbox Code Playgroud)

我需要实现这一点:

Oct 12 02:28:26 server program: 192.168.1.105 text for 1.105 
Oct 12 02:30:00 server program: 192.168.1.104 text for 1.104
Oct 12 02:30:23 server program: 192.168.1.103 text for 1.103
Oct 12 02:32:39 server program: 192.168.1.101 text for 1.101
Run Code Online (Sandbox Code Playgroud)

如何将新输出发送到文件?我试过这个:

awk '!_[$6]++ {a=$6} END{print a}' logfile
Run Code Online (Sandbox Code Playgroud)

但它没有给我预期的结果。如何使用 awk 或 sed 只给我上次看到字符串匹配或基于日期/时间的唯一行?

Wil*_*ard 5

如果您要进行第二遍(您非常必须这样做),您最好只存储行号而不是完整记录。它使逻辑更容易。

awk 'NR == FNR {if (z[$6]) y[z[$6]]; z[$6] = FNR; next} !(FNR in y)' logfile logfile
Run Code Online (Sandbox Code Playgroud)

正确性证明:

在处理每一行结束时,到目前为止处理的每个行号要么是 中的值z要么是 中的索引(不是值)y,但绝不是两者兼而有之。

由 in 值表示的行在z每次迭代结束时准确且仅是迄今为止针对每个 IP 地址看到的最新记录。

y因此,的索引是我们希望打印的确切行。