Найти максимальные значения в n-м столбце для каждого отдельного значения в 1-м столбце в bash - PullRequest
0 голосов
/ 21 сентября 2018

У меня есть файл из 3 столбцов, и я хочу найти максимальное значение третьего столбца со строками с таким же первым столбцом, а также иметь второй выходной столбец.

Ввод:

1   234   0.005
1   235   0.060
1   236   0.001
2   234   0.010
2   235   0.003
2   236   0.003
3   234   0.004
3   235   0.100
3   236   0.004

Желаемый результат:

1   235   0.060
2   234   0.010
3   235   0.100

Я нашел этот совет из предыдущих вопросов, но я не знаю, как получить и второй столбец:

!($1 in max) || $3>max[$1] { max[$1] = $3 }
END {
     PROCINFO["sorted_in"] = "@ind_num_asc"
     for (key in max) {
         print key, max[key]
         }
     }

Ответы [ 5 ]

0 голосов
/ 22 сентября 2018
$ sort -k1,1n -k3,3nr file | awk '!seen[$1]++'
1   235   0.060
2   234   0.010
3   235   0.100
0 голосов
/ 21 сентября 2018

Это должно работать в любом современном awk (не только в GNU):

$ awk '!a[$1]||$3>b[$1]{a[$1]=$0;b[$1]=$3} END {for(i in a)print a[i]}' file | sort -n

Выделено для удобства чтения:

  • !a[$1] || $3>b[$1] - Если мы не виделипервый столбец перед ИЛИ третий столбец бьет нашу предыдущую запись,
  • {a[$1]=$0;b[$1]=$3} - затем сохраните текущую строку в одном массиве, а значение сравнения - в другом массиве.
  • END {for(i in a)print a[i]} -Как только мы обработаем все входные данные, напечатайте каждую строку из нашего массива хранения.
  • sort -n - отсортируйте численно.Должно работать с любым типом sort.

Очистить как грязь?

В этом решении хранятся целые строки ($0), а не содержимое отдельных полей, поэтому его будет строк ввода, а не пересоздает строк ввода.Это может быть полезно, если вас устраивает расщепление полей по умолчанию для сбора полей для сравнения, но у вас есть столбцы или вкладки, которым вы хотите, чтобы ваш вывод соответствовал.

0 голосов
/ 21 сентября 2018

Не могли бы вы попробовать следующее.Он должен выдавать выходные данные в том же порядке, что и последовательность ввода Input_file.

awk '
!a[$1]++{
  b[++count]=$1
}
{
  c[$1]=(c[$1]>$NF?c[$1]:$NF)
  d[$1]=(c[$1]>$NF?d[$1]:$1 OFS $2)
}
END{
  for(i=1;i<=count;i++){
    print d[b[i]],c[b[i]]
  }
}'  Input_file

Вывод будет следующим:

1 235 0.060
2 234 0.010
3 235 0.100

Объяснение: Добавление объяснения для приведенного выше кода тоже здесь.

awk '
!a[$1]++{                              ##Checking condition if array named a has NO occurrence of $1 in it then do following.
  b[++count]=$1                        ##Create array b whose index is variable count with increasing value of 1 each time value is $1 for it.
}
{
  c[$1]=(c[$1]>$NF?c[$1]:$NF)          ##Creating array c value index is $1 and checking if $NF value is greater then its value then change it to $NF else no change.
  d[$1]=(c[$1]>$NF?d[$1]:$1 OFS $2)    ##Creating array d value index is $1 and checking if $NF value is greater then its value then change it to $NF else no change.
}
END{                                   ##Starting end block of awk program here.
  for(i=1;i<=count;i++){               ##Starting for loop here from i value 1 to till value of count.
    print d[b[i]],c[b[i]]              ##Printing value of array d whose index is value of b[i] and array c whose index is b[i].
  }
}' Input_file                          ##mentioning Input_file name here.
0 голосов
/ 21 сентября 2018
$ sort -k1n -k3nr file | uniq -w 1
1   235   0.060
2   234   0.010
3   235   0.100

Используйте sort для сортировки по полям 1 и 3, в обратном порядке.Затем используйте uniq и сравните только 1-й символ.

Еще один, использующий GNU awk:

$ awk '{
    a[$1][$3]=$0 }
END {   
    PROCINFO["sorted_in"]="@ind_num_asc"       # first for in ascending order
    for(i in a) {
        PROCINFO["sorted_in"]="@ind_num_desc"  # next for in descending
        for(j in a[i]) {
            print a[i][j]
            break
        }
    }
}' file
1   235   0.060
2   234   0.010
3   235   0.100
0 голосов
/ 21 сентября 2018

Вы можете использовать это awk:

awk '!($1 in max) || $3 > max[$1] { max[$1] = $3; two[$1] = $2 }
END { PROCINFO["sorted_in"] = "@ind_num_asc"
   for (i in max) print i, two[i], max[i]
}' file

1 235 0.060
2 234 0.010
3 235 0.100
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...