linux - 删除日志文件中的重复行

标签 linux bash awk sed

我正在尝试从重复的行中清理我的日志文件。 首先,我使用带有 uniq -d 标志的排序命令,它帮助我删除重复项,但没有解决我的问题。

sort pnum.log | uniq -d

排序命令的输出。

PNUM-1233: [App] [Tracker] Text
PNUM-1233: [App] [Tracker] Text
PNUM-1236: [App] [Tracker] Text ddfg   
PNUM-1236: [App] [Tracker] Text ddfg
PNUM-1234: [App] [Tracker] Tex 123  ssd
PNUM-1235: [App] [Tracker] Text 1dbg  
PNUM-1234: [App] [Tracker] Text 123 ssd vp

排序命令删除重复项,但不幸的是,我还需要删除重复 PNUM 的行,并只保留一个唯一的 PNUM,示例输出中的文本较长,它将是“PNUM-1234: [App] [Tracker] Text 123 ssd vp”和其他 2 行 PNUM-1234 应该从文件中删除。如何实现?有没有像 sort 这样的 linux 命令可以帮助我排序?

期望是:

PNUM-1233: [App] [Tracker] Text
PNUM-1236: [App] [Tracker] Text ddfg   
PNUM-1235: [App] [Tracker] Text 1dbg  
PNUM-1234: [App] [Tracker] Text 123 ssd vp

最佳答案

排序 | uniq -d 不会删除重复项,它会打印每批 重复行中的一个。您可能应该改用 sort -u - that 将删除重复项。

但是要回答你问的问题:

$ awk '{print length($0), $0}' file | sort -k1,1rn | awk '!seen[$2]++' | cut -d' ' -f2-
PNUM-1234: [App] [Tracker] Text 123 ssd vp
PNUM-1236: [App] [Tracker] Text ddfg
PNUM-1235: [App] [Tracker] Text 1dbg
PNUM-1233: [App] [Tracker] Text

第一个 awk 命令只是在每行前面加上它的长度,因此后续的 sort 可以对所有行进行最长优先排序,然后是第二个 awk 仅在第一次出现键字段值时输出该行(现在是具有该键值的最长行)然后 cut 删除第一个 的行长度awk 添加。

按顺序:

$ awk '{print length($0), $0}' file
31 PNUM-1233: [App] [Tracker] Text
31 PNUM-1233: [App] [Tracker] Text
39 PNUM-1236: [App] [Tracker] Text ddfg
36 PNUM-1236: [App] [Tracker] Text ddfg
39 PNUM-1234: [App] [Tracker] Tex 123  ssd
38 PNUM-1235: [App] [Tracker] Text 1dbg
42 PNUM-1234: [App] [Tracker] Text 123 ssd vp
$
$ awk '{print length($0), $0}' file | sort -k1,1rn
42 PNUM-1234: [App] [Tracker] Text 123 ssd vp
39 PNUM-1234: [App] [Tracker] Tex 123  ssd
39 PNUM-1236: [App] [Tracker] Text ddfg
38 PNUM-1235: [App] [Tracker] Text 1dbg
36 PNUM-1236: [App] [Tracker] Text ddfg
31 PNUM-1233: [App] [Tracker] Text
31 PNUM-1233: [App] [Tracker] Text
$
$ awk '{print length($0), $0}' file | sort -k1,1rn | awk '!seen[$2]++'
42 PNUM-1234: [App] [Tracker] Text 123 ssd vp
39 PNUM-1236: [App] [Tracker] Text ddfg
38 PNUM-1235: [App] [Tracker] Text 1dbg
31 PNUM-1233: [App] [Tracker] Text
$
$ awk '{print length($0), $0}' file | sort -k1,1rn | awk '!seen[$2]++' | cut -d' ' -f2-
PNUM-1234: [App] [Tracker] Text 123 ssd vp
PNUM-1236: [App] [Tracker] Text ddfg
PNUM-1235: [App] [Tracker] Text 1dbg
PNUM-1233: [App] [Tracker] Text

如果同一键值的多行长度相同,则您没有说明要打印哪一行,因此上面只会随机输出其中一行。如果这是一个问题,那么您可以使用 GNU sort 并添加 -s 参数(对于 stable sort)或将命令行更改为 awk '{print length( $0), NR, $0}' 文件 |排序-k1,1rn -k2,2n | awk '!seen[$3]++' | cut -d' ' -f3- - 在这两种情况下,这将确保在这种冲突中输出的行将是输入中出现的第一个。

关于linux - 删除日志文件中的重复行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62833254/

相关文章:

bash - 打印作为变量传递的字段列表

bash - 在 awk 中结合 if 和 NR

linux - 如何将txt文件追加到之前创建的最后一行

linux - Linux 上的伽罗瓦域计算

linux - 使用 sched_setaffinity 固定到核心后如何取消固定线程?

python - 在 python linux 中执行命令时在 python 中给出响应 os.system()

python - 用 python 为 arm 交叉编译 gdb 失败

linux - Linux 中花括号的评估

linux - 在 Linux 中使用 $ 符号访问每一行

bash - 替换字符串每第 n 次出现的位置