Как напечатать соответствующую строку для максимального значения последнего столбца? - PullRequest
0 голосов
/ 14 февраля 2019

Я пытаюсь напечатать всю строку для максимального значения последнего столбца на основе второго последнего столбца -

входной файл: file1.txt

2019-01-16 08:00:00.0   test1   28848859233
2019-01-16 08:00:00.0   test2   902006478
2019-01-16 08:00:00.0   test3   5385892905
2019-01-16 08:00:00.0   test1   4194204503
2019-01-15 08:00:00.0   test1   115598553821
2019-01-15 08:00:00.0   test2   59736397346
2019-01-15 08:00:00.0   test3   5508381147
2019-01-15 08:00:00.0   test4   39377518945
2019-01-15 08:00:00.0   test5   35371907528
2019-01-14 08:00:00.0   test1   115598553811
2019-01-14 08:00:00.0   test3   5408381147
2019-01-14 08:00:00.0   test4   346377518945

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

2019-01-15 08:00:00.0   test1   115598553821
2019-01-15 08:00:00.0   test2   59736397346
2019-01-15 08:00:00.0   test3   5508381147
2019-01-14 08:00:00.0   test4   346377518945
2019-01-15 08:00:00.0   test5   35371907528

Когда я попытался использовать его для управления столбцом (3) и максимальным значением из нужного столбца (4), это сработало

awk '{if (a[$3] < $4) {a[$3]=$4}} END {PROCINFO["sorted_in"] = "@ind_num_asc" ; for (i in a) {print i, a[i]}}' file1.txt
test1 115598553821
test2 59736397346
test3 5508381147
test4 346377518945
test5 35371907528

Я попытался использовать команду ниже, чтобы напечатать всю строку, но не сделалт работа -

awk '{if (a[$3] < $4) {a[$3]=$4;b[$0]=a[$3]}} END {PROCINFO["sorted_in"] = "@ind_num_asc" ;for (i in b) {print i, b[i]}}' file1.txt
2019-01-15 08:00:00.0   test4   39377518945 39377518945
2019-01-15 08:00:00.0   test2   59736397346 59736397346
2019-01-15 08:00:00.0   test3   5508381147 5508381147
2019-01-16 08:00:00.0   test2   902006478 902006478
2019-01-14 08:00:00.0   test4   346377518945 346377518945
2019-01-15 08:00:00.0   test5   35371907528 35371907528
2019-01-15 08:00:00.0   test1   115598553821 115598553821
2019-01-16 08:00:00.0   test3   5385892905 5385892905
2019-01-16 08:00:00.0   test1   28848859233 28848859233

Ответы [ 5 ]

0 голосов
/ 14 февраля 2019

с sort/awk сотрудничество

$ sort -k3,3 -k4nr file | awk '!a[$3]++'

2019-01-15 08:00:00.0   test1   115598553821
2019-01-15 08:00:00.0   test2   59736397346
2019-01-15 08:00:00.0   test3   5508381147
2019-01-14 08:00:00.0   test4   346377518945
2019-01-15 08:00:00.0   test5   35371907528
0 голосов
/ 14 февраля 2019

Решение не для awk с использованием всегда удобного GNU datamash :

$ datamash -Wsf groupby 3 max 4 < example.txt | cut -f 1-4
2019-01-15  08:00:00.0  test1   115598553821
2019-01-15  08:00:00.0  test2   59736397346
2019-01-15  08:00:00.0  test3   5508381147
2019-01-14  08:00:00.0  test4   346377518945
2019-01-15  08:00:00.0  test5   35371907528
0 голосов
/ 14 февраля 2019

Попробуйте, пожалуйста:

$ awk '!n[$3] || n[$3]<$4{n[$3]=$4;l[$3]=$0;}END{for(i in l) print l[i]}' file1.txt
2019-01-15 08:00:00.0   test1   115598553821
2019-01-15 08:00:00.0   test2   59736397346
2019-01-15 08:00:00.0   test3   5508381147
2019-01-14 08:00:00.0   test4   346377518945
2019-01-15 08:00:00.0   test5   35371907528

Я переместил условие наружу, для краткости и эффективности.
Также я изменил key на значение $3, где вы используете всестрока как ключ ($0).
Поскольку вы пытаетесь вывести всю строку, они должны быть значением, а значения столбца 3 должны быть ключами.

0 голосов
/ 14 февраля 2019

Я выяснил проблему, я должен был сохранить $0 в колонке управления (3) для массива b, когда желаемое условие выполнено (найти максимальное значение из $NF сохранить в колонке управления (3) a [$ 3] =$ 4) не массив a столбца (3) в массив b со всей строкой.как то так -

awk '{if (a[$3] < $4) {a[$3]=$4;b[$3]=$0}} END {PROCINFO["sorted_in"] = "@ind_num_asc" ;for (i in b) {print b[i]}}' file1.txt
2019-01-15 08:00:00.0   test1   115598553821
2019-01-15 08:00:00.0   test2   59736397346
2019-01-15 08:00:00.0   test3   5508381147
2019-01-14 08:00:00.0   test4   346377518945
2019-01-15 08:00:00.0   test5   35371907528
0 голосов
/ 14 февраля 2019

1-е решение: Не могли бы вы попробовать следующее.

awk '
{
  a[$3]=$NF>a[$3]?$NF:a[$3]
  b[$3,$NF]=$1 OFS $2
}
END{
  for(i in a){
    print b[i,a[i]],i,a[i]
  }
}'   Input_file

2-е решение: После будетпозаботьтесь о том, чтобы выходная последовательность $ 3 (3-е поле) была такой же, как в 3-й последовательности полей Input_file.

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

Объяснение приведенного выше кода:

awk '
!c[$3]++{                                ##Checking condition if array c with index $3 of current line is coming first time in array c if this is TRUE then assign it $3 as an index current line.
  d[++count]=$3                          ##Creating an aray d whose index as count variable value which will increment each time cursor comes here and assigning value of this array d to $3 here.
}                                        ##Closing block for array c here.
{                                        ##Starting block which will execute in all the lines for Input_file.
  a[$3]=$NF>a[$3]?$NF:a[$3]              ##Creating an array named a whose value is $NF of current line if value of $NF>a[$3] else it is NOT changing.
  b[$3,$NF]=$1 OFS $2                    ##Creating an array b whose index is $3,$NF and value will be $1 OFS $2.
}                                        ##Closing block here.
END{                                     ##Starting END block of awk program here.
  for(i=1;i<=count;i++){                 ##Starting a for loop from i=1 to till value of count here.
   print b[d[i],a[d[i]]],d[i],a[d[i]]    ##Printing value of array b whose index is d[i], array a whose index is d[i] value AND value of d[i].
  }                                      ##Closing block for, for loop now.
}'  Input_file                           ##Mentioning Input_file name here.


РЕДАКТИРОВАТЬ: Добавление причины, почему попытка OP не работает.

Код OP:

awk '{if (a[$3] < $4) {a[$3]=$4;b[$0]=a[$3]}} END {PROCINFO["sorted_in"] = "@ind_num_asc" ;for (i in b) {print i, b[i]}}' file1.txt

Объяснение ИМХО, почему код не работает: Поскольку значения массива b НИКОГДА не удаляются или не изменяются (всякий раз, когда значение 3-го столбца меньше или больше его предыдущих значений), поэтомуэто причина, по которой вы проходите через массив b, тогда он печатает все значения массива b.Нам нужно менять значение массива b всякий раз, когда значение для 3-го поля меньше его предыдущего значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...