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

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

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

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 

我需要实现这个目标:

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

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

awk '!_[$6]++ {a=$6} END{print a}' logfile

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

答案1

如果您打算进行第二遍(您很可能必须这样做),您也可以只存储行号而不是完整记录。它使逻辑更容易。

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

正确性证明:

在处理每一行结束时,到目前为止处理的每行号是任何一个中的一个值z或者中的索引(不是值)y,但不能同时存在。

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

因此,的索引y正是我们希望的线不是打印。

答案2

保存整行(用作$6数组索引)并END迭代数组的元素:

awk '{z[$6]=$0};END{for (i in z) print z[i]}' logfile

但结果不会被排序...你可以这样做:

awk '{z[$6]=NR" "$0};END{for (i in z) print z[i]}' logfile | sort -k1,1n | cut -f2-
### this space ^ is a literal TAB

这保存了行号。加上行内容即可按行号排序。


其他方法涉及第二遍以按日期排序(因为这是日志),但如果输入包含重复行(即整行),则会打印重复条目 - 例如grep

awk '{z[$6]=$0};END{for (var in z) print z[var]}' logfile | grep -Fxf- logfile

或仅与awk

awk 'NR==FNR{z[$6]=$0;next}
FNR==1{for (var in z) y[z[var]]}
$0 in y' logfile logfile

答案3

如果您只有同一天的线路,您可以像这样处理:

sort -k6 -k3r logfile | uniq -f3 | sort -k3

如果您排队的时间超过一天,您仍然可以使用这种基本方法,但您的排序必须变得更加巧妙。上面的命令只能处理一天的记录,因为它使用时间戳的时间部分(例如02:28:26)作为整个时间戳的代理。

答案4

通过按行反转文件,逻辑变得更简单

$ tac logfile | awk '!seen[$6]++' | tac
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 

相关内容