Удалить строки, когда три столбца идентичны

У меня есть файл, разделенный табуляцией, и я хочу удалить строки (сохранить одну копию), которые идентичны только в первых трех столбцах. Я предпочитаю делать это с помощью unix, например, awk или uniq.

Входной файл:

Supercontig_1.1 241783  286397  5677    52
Supercontig_1.1 241783  286397  5678    53
Supercontig_1.1 241783  286397  5679    53
Supercontig_1.2 10500  25700  3000    57
Supercontig_1.2 10500  25700  3001    59
Supercontig_1.2 10500  25700  3002    59
Supercontig_1.3 2000  7000  5686    60
Supercontig_1.3 2000  7000  5687    60

Выход:

 Supercontig_1.1 241783  286397  5677    52
 Supercontig_1.2 10500  25700  3000    57
 Supercontig_1.3 2000  7000  5686    60

person Jon    schedule 18.10.2012    source источник


Ответы (2)


Один из способов использования awk:

awk '!array[$1,$2,$3]++' file.txt

Результаты:

Supercontig_1.1 241783 286397 5677 52
Supercontig_1.2 10500 25700 3000 57
Supercontig_1.3 2000 7000 5686 60
person Steve    schedule 18.10.2012
comment
осторожно - объединение таких полей приведет к неправильному выводу, если, например, первая строка содержит 1 23 4, а вторая строка содержит 1 2 34, поскольку они обе будут отображаться на 1234. Вам нужно использовать псевдомногомерный массив для этого: !a[$1,$2,$3]++. - person Ed Morton; 18.10.2012
comment
Спасибо @ЭдМортон! - небольшая оплошность. Думаю, я часто использую FS, но даже с этим могут возникнуть проблемы. Я провел некоторое тестирование, запятая фактически устанавливает нулевой разделитель: \0. Интересно. - person Steve; 18.10.2012
comment
Запятая преобразуется в значение встроенной переменной SUBSEP. Вот почему я сказал псевдомногомерный, потому что на самом деле это не мульти-D, вы просто получаете один индекс, состоящий из $1 SUBSEP $2 SUBSEP $3. Пусть вы можете сделать for (idx in array) { split(idx,idxA,SUBSEP);...}, чтобы получить $1, $2 и $3 обратно в массив idxA. - person Ed Morton; 18.10.2012
comment
@EdMorton: вау, я все еще учусь awk. Раньше не прикасался к SUBSEP. Я обычно использую FS. Классный совет, спасибо! - person Steve; 18.10.2012

этот oneliner делает свое дело:

awk '!a[$1$2$3]++' file

проверить

kent$  echo "Supercontig_1.1 241783  286397  5677    52
dquote> Supercontig_1.1 241783  286397  5678    53
dquote> Supercontig_1.1 241783  286397  5679    53
dquote> Supercontig_1.2 10500  25700  3000    57
dquote> Supercontig_1.2 10500  25700  3001    59
dquote> Supercontig_1.2 10500  25700  3002    59
dquote> Supercontig_1.3 2000  7000  5686    60
dquote> Supercontig_1.3 2000  7000  5687    60
dquote> "|awk '!a[$1$2$3]++'
Supercontig_1.1 241783  286397  5677    52
Supercontig_1.2 10500  25700  3000    57
Supercontig_1.3 2000  7000  5686    60
person Kent    schedule 18.10.2012