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

gev0vcfq  于 2023-05-16  发布在  Linux
关注(0)|答案(5)|浏览(145)

此问题已在此处有答案

How to delete duplicate lines in a file without sorting it in Unix(9个回答)
3天前关闭。
我正试图清除日志文件中的重复行。首先,我使用带有uniq -d标志的排序命令,它帮助我删除重复项,但没有解决我的问题。

sort pnum.log | uniq -d

sort命令的输出。

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:[应用程序] [跟踪器]文本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
c86crjj0

c86crjj01#

sort | 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排序并添加-s参数(对于stable sort)或将命令行更改为awk '{print length($0), NR, $0}' file | sort -k1,1rn -k2,2n | awk '!seen[$3]++' | cut -d' ' -f3--在这两种情况下,这将确保在这种冲突中的行输出将是输入中出现的第一个。

cnjp1d6j

cnjp1d6j2#

假设您已经删除了重复的行,您可以使用下面的awk语句来只打印基于第一列PUM-XXXX的唯一行,但选择最长的一列。

awk -F":" '{ if (length($0)> length(to_print[$1])) {to_print[$1]=$0} } END { for (key in to_print) { print to_print[key] } }'

因此,您必须创建一个数组to_print,以跟踪最大的行。最后,它会打印出这个数组。

0yycz8jy

0yycz8jy3#

因为第一个字段似乎具有恒定的字符计数,所以您可以:

uniq -w 10 file
aor9mmx1

aor9mmx14#

这些命令应该能够从pnum.log文件中删除具有重复/重复PNUM的行,仅保留一个具有最长文本的唯一PNUM,并保持其相对行顺序:

cat pnum.log | awk -F":" '
{ if (length($0)> length(line[$1])) {line[$1]=NR":"$0} }
END { for (key in line) { print line[key] } }
' | sort -t: -nk1 | cut -d: -f2-
jljoyd4f

jljoyd4f5#

您可以使用下面的代码,出于调试目的,您可以使用额外列出的代码。它可以帮助任何人搜索。

sort -u pnum.log #this will remove the duplicates

uniq –c pnum.log #this will print the count 

uniq –u pnum.log #prints only unique lines of the log

相关问题