удалить повторяющиеся строки в файле журнала - PullRequest
2 голосов
/ 10 июля 2020

Я пытаюсь очистить свой файл журнала от повторяющихся строк. Прежде всего, я использую команду sort с флагом 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: [Приложение] [Tracker] Text 123 ssd vp» и 2 другие строки с PNUM-1234 следует удалить из файла. Как этого добиться? Есть ли какие-нибудь команды linux, такие как sort, которые могут помочь мне сортировать?

и ожидание будет:

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

Ответы [ 4 ]

3 голосов
/ 11 июля 2020

sort | uniq -d не удаляет дубликаты, а печатает по одной из каждого пакета строк, которые являются дубликатами. Вероятно, вам следует использовать sort -u вместо - , что удалит дубликаты.

Но чтобы ответить на ваш вопрос:

$ 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- - в обоих случаях это обеспечит вывод строки в таком конфликте первым. тот, который присутствовал во входных данных.

2 голосов
/ 10 июля 2020

Поскольку кажется, что первое поле имеет постоянное количество символов, вы можете:

uniq -w 10 file
2 голосов
/ 10 июля 2020

Предполагая, что вы уже удалили повторяющиеся строки, вы можете использовать следующий оператор 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, который будет отслеживать самую большую строку. и в конце он распечатает этот массив.

1 голос
/ 10 июля 2020

Эти команды должны иметь возможность удалять строки с повторяющимися / повторяющимися PNUM из вашего файла pnum.log, сохранять только один уникальный 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-
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...