2014-01-02 3 views
0

Я хочу получить верхние N наиболее распространенных значений поля в CSV-файле с их суммой в другом поле. Как я могу это сделать с awk?Список наиболее распространенных значений с их соответствующей суммой

Пусть мой файл является:

v1,45 
v3,20 
v2,500 
v3,100 
v2,200 
v1,55 
v3,50 
v1,10 

и мне нужно N = 2 не более 1 значения происходящих полей с их суммой соответствующих поле2 ценности в этом случае вывод будет:

v1,110 
v3,170 

ответ

1
awk -F, '{a[$1]+=$2;c[$1]++}END{for(k in c)print c[k], k","a[k]}' file|sort -nr|awk 'NR<3&&$0=$2' 

его можно решить за один awk, но это более просто. :)

, если вы хотите изменить ваш N, просто измените последний AWK CMD NR<3...

+0

Не могли бы вы толковать это более подробно? – user3144923

+0

@ user3144923 первый awk, будет делать сумму на одном и том же 'vx' и генерировать вывод, подобный' 3 v1,110', 3 - это число встречаемости, вторая часть (разделенная пробелом) - это то, что мы хотим, передаем это ' sort -nr' decending сортировать по числу. результат снова возвращается к awk, мы берем только первые две записи и удаляем первый столбец, который был '3'. – Kent

+0

Как вы можете масштабировать значения второго поля на выходе? например, мне нужно умножить все значения столбцов на значение, вычисленное в bash и вне awk, например $ scale – user3144923

1

В Gnu AWK есть asort функция, так что вы могли бы сделать

gawk -f a.awk file 

где a.awk является:

BEGIN { FS=OFS="," } 
{ 
    a[$1]++ 
    b[$1]+=$2 
} 

END { 
    for (i in a) 
     a[i]=a[i]"\t"i 
    n=asort(a) 
    for (i=1; i<=n; i++) { 
     split(a[i],c,"\t") 
     ind[i]=c[2] 
    } 
    for (i=n; i>n-2; i--) 
     print ind[i],b[ind[i]] 
} 

Выход:

v3,170 
v1,110 
Смежные вопросы