2016-09-01 6 views
0

У меня есть огромный файл (my_file.txt) с ~ 8000000 линий, выглядит следующим образом:удалить линии на основе значения двух столбцов

1 13110 13110 rs540538026 0 NA -1.33177622457982 
1 13116 13116 rs62635286 0 NA -2.87540758021667 
1 13118 13118 rs200579949 0 NA -2.87540758021667 
1 13013178 13013178 rs374183434 0 NA -2.22383195384362 
1 13013178 13013178 rs11122075 0 NA -1.57404917386838 

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

awk -F"\t" '!seen[$2, $3]++' my_file.txt 

Но я не знаю, как сделать часть об удалении дубликата с более низким значением, желаемые выход будет следующим:

1 13110 13110 rs540538026 0 NA -1.33177622457982 
1 13116 13116 rs62635286 0 NA -2.87540758021667 
1 13118 13118 rs200579949 0 NA -2.87540758021667 
1 13013178 13013178 rs11122075 0 NA -1.57404917386838 

Скорость является проблемой, так что я мог бы использовать AWK, Sed или другую команду Баша Благодаря

ответ

3
$ awk '(i=$1 FS $2 FS $3) && !(i in seventh) || seventh[i] < $7 {seventh[i]=$7; all[i]=$0} END {for(i in a) print all[i]}' my_file.txt 
1 13013178 13013178 rs11122075 0 NA -1.57404917386838 
1 13116 13116 rs62635286 0 NA -2.87540758021667 
1 13118 13118 rs200579949 0 NA -2.87540758021667 
1 13110 13110 rs540538026 0 NA -1.33177622457982 

Благодаря @fedorqui для продвинутой индексации. : D

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

(i=$1 FS $2 FS $3) && !(i in seventh) || $7 > seventh[i] { # set index to first 3 fields 
        # AND if index not yet stored in array 
             # OR the seventh field is greater than the previous value of the seventh field by the same index: 
    seventh[i]=$7      # new biggest value 
    all[i]=$0       # store that record 
} 
END { 
    for(i in all)      # for all stored records of the biggest seventh value 
     print all[i]     # print them 
} 
+0

Не могли бы вы объяснить немного то, что команда не @JamesBrown? Спасибо за ответ – user2380782

+0

'seen' является плохим именем для этого массива. Идиоматически мы всегда используем имя массива 'seen', чтобы представлять ** просто ** набор индексов, которые были замечены, а не как массив значений count или max или что-то еще. В этом случае ваше имя массива должно быть 'max'. –

+0

Исправлено «замечено». –

Смежные вопросы