Сортировка минимального значения для каждого повторного имени - PullRequest
0 голосов
/ 16 января 2019

Я пытаюсь отсортировать минимальное значение из текстового файла, который содержит повторяющиеся имена, но разные значения.

Peter 0.19827
Wilson 0.99234
Peter 0.08234
May -0.45623
Joe 0.88765
Wilson -0.88341
Joe 0.99943

Я пробовал это, но это не работает: (Я предпочитаю awk one-liner)

cat aaa.txt | sort -k2nr | awk '{if ($2<min[$1]) {min[$1]=$2}}END{for (i in min) {print i,min[i]}}' | less

Ожидаемый результат:

Peter 0.08234
Wilson -0.88341
May -0.45623
Joe 0.88765

Ответы [ 5 ]

0 голосов
/ 16 января 2019

Вы также можете попробовать Perl.

$ cat tatt.txt
Peter 0.19827
Wilson 0.99234
Peter 0.08234
May -0.45623
Joe 0.88765
Wilson -0.88341
Joe 0.99943
$ perl -lane ' @t=@{$kv{$F[0]}} ;push(@t,$F[1]);$kv{$F[0]}=[@t]; END { for(keys %kv) { @t=sort @{$kv{$_}}; print "$_,$t[0]" }} ' tatt.txt
Joe,0.88765
May,-0.45623
Wilson,-0.88341
Peter,0.08234
$
0 голосов
/ 16 января 2019

Еще один awk:

$ awk '!($1 in a)||a[$1]>$2{a[$1]=$2}END{for(i in a)print i,a[i]}' file

Выход:

May -0.45623
Peter 0.08234
Joe 0.88765
Wilson -0.88341

Разъяснения:

$ awk '
!($1 in a) || a[$1]>$2 {  # if the key (name) has not yet been seen or its value is smaller
    a[$1]=$2              # store it to hash a
}
END {                     # after processing all the records
    for(i in a)           # go thru the stored keys
        print i,a[i]      # print them and their value
}' file
0 голосов
/ 16 января 2019

Без бесполезного cat или бесполезного sort и с исправленной ошибкой

awk '!($1 in min) || $2<min[$1] { min[$1] = $2 }
    END { for (i in min) print i,min[i] }' aaa.txt

Ошибка в том, что неинициализированные элементы массива по умолчанию обнуляются, поэтому вы теряли те, у которых был положительный минимум.

Я сложил это для разборчивости; при желании вы можете удалить встроенный перевод строки.

Если важно сохранить порядок, вы можете добавить второй массив, который отслеживает порядок появления ключей.

awk '!($1 in min) { k[++i] = $1; min[$1] = $2}
    $2<min[$1] { min[$1] = $2 }
END { for (j=1; j<=i; ++j) print k[j],min[k[j]] }' aaa.txt
0 голосов
/ 16 января 2019

Еще один способ, если заказ не является проблемой:

sort -k 1,1 -k 2n,2 file | awk '!_[$1]++'
0 голосов
/ 16 января 2019

Если вас не беспокоит порядок вашего первого поля из Input_file, попробуйте выполнить следующее.

awk '{{a[$1]=(a[$1]>$2?a[$1]?a[$1]:$2:$2)} END{for(i in a){print i,a[i]}}' Input_file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...