Как я могу заказать текстовый файл с определенными критериями? - PullRequest
3 голосов
/ 04 июля 2019

Я не могу исправить проблему с текстовым файлом, так как я новичок с командой linux и / или скриптом bash.

У меня есть такой текстовый файл:

object1 10.603  0.757
object1 10.523  0.752
object1 10.523  0.752
object1 10.456  0.747
object1 10.456  0.747
object1 10.271  0.734
object2 11.473  0.194
object2 11.460  0.194
object2 11.445  0.191
object2 11.421  0.190
object3 9.272   0.12
object3 9.236   0.12
object3 8.814   0.119
object3 0.968   0.119
object3 10.959  0.119

и я должен выполнить для этого файла определенную операцию вырезания и сортировки: для каждой строки, содержащей слова «object1», «object2» и т. Д., Я хочу напечатать только строку, имеющую самые высокие значения в соответствии с третий столбец; затем я хочу отсортировать вывод этой операции по значениям третьего столбца.

Для ясности вывод должен выглядеть так:

object1 10.603  0.757
object2 11.473  0.194
object3 9.272   0.12

Есть предложения по использованию команды linux и / или скрипта bash?

спасибо всем

Ответы [ 4 ]

2 голосов
/ 04 июля 2019

Использование sort и awk:

sort -k1,1 -k3rn -k2rn file.txt | awk '!seen[$1] {print} {seen[$1]++}'

sort сначала сортирует первое поле, затем третье в обратном порядке, затем второе в обратном (последнее может быть опущено, если это не имеет значения). Тогда awk печатает только первые найденные уникальные строки, учитывая только первое поле.

1 голос
/ 04 июля 2019

Вот еще один awk скрипт, который выполняет эту работу.

script.awk

$1 == currObj{    # for each reoccouring object
    if ( ($3 + 0) > maxArr[$1] ) maxArr[$1] = $3 + 0;  # identify the max and store in maxArr
    next;         # skip to read next line
}
{                 # for each line having new object
    currObj = $1; # store current object in 1st field into variable currObj
    maxArr[$1] = $3; # reset the maxArr to current value
    fld2Arr[$1] = $2; # store 2nd field into an array;
}
END {             # post processing
    for (i in maxArr) print i, fld2Arr[i], maxArr[i]; # print for each index the array values
}

выполняется:

awk -f script.awk input.txt

вывод:

object1 10.603 0.757
object2 11.473 0.194
object3 9.272 0.12
1 голос
/ 04 июля 2019

Один в awk:

$ awk '{
    if(m[$1]<$3) {   # if previous max for 1st field val is bigger
        m[$1]=$3     # replace max value
        r[$1]=$0     # store record
    }
}
END {                # in the end
    for(i in r)      # iterate hashed records
        print r[i]   # and output
}' file

Вывод (в произвольном порядке, если требуется сортировка, используйте sort или GNU awk с PROCINFO["sorted_in"]="@ind_str_asc" в начале блока END{}):

object1 10.603  0.757
object2 11.473  0.194
object3 9.272   0.12

Обновление :

Другое использование sort и uniq, shuf только для демонстрации:

$ sort -k1r -k3n <(shuf file) | uniq -w 7
object3 9.272   0.12
object2 11.473  0.194
object1 10.603  0.757

Для группировкипервое поле, которое я использовал: (man uniq):

-w, --check-chars=N
      compare no more than N characters in lines
0 голосов
/ 04 июля 2019

Используйте awk для фильтрации данных перед их сортировкой.

awk 'a[$1] < $3 {a[$1] = $3; b[$1]=$0} END {for (i in a) print b[i]}' input | sort -k3rn
...