
Я ищу код для удаления дубликатов строк после сравнения первого шаблона, разделенного табуляцией:
Пример: ( ↦
= табуляция)
car ↦ ab ↦ 38/43
car ↦ ca ↦ 2/34
house ↦ ca ↦ 34/34
house ↦ d ↦ 2/3
house ↦ ht ↦ 3/7
boat ↦ as ↦ 5/5
Я хочу удалить дубликаты строк с тем ограничением, что строка ca
во втором поле не должна быть удалена.
Результат:
car ↦ ca ↦ 2/34
house ↦ ca ↦ 34/34
boat ↦ as ↦ 5/5
Есть идеи? Я пробовал sed и sort, но не получил рабочего кода.
решение1
Я предполагаю, что если есть повторяющиеся записи, то всегда найдется одна со ca
вторым полем.
В вашем примере данных все строки, которые имеют одинаковое первое поле, сгруппированы вместе, но вы не упомянули, всегда ли это так. Если это так, то задача немного упрощается, но скрипт awk ниже будет работать, даже если совпадающие строки не сгруппированы вместе.
дедупликация.awk
#!/usr/bin/awk -f
{
if (!($1 in lines) || ($2 == "ca"))
lines[$1] = $0
}
END{
for (i in lines)
print lines[i]
}
Если входной файл называется data
, вы должны запустить его так:
awk -f dedup.awk data
или
awk -F '\t' -f dedup.awk data
чтобы убедиться, что он использует табуляцию в качестве разделителя полей; разделителем полей по умолчанию является один или несколько пробелов и/или табуляций. Fields
Дополнительную информацию см. на странице руководства gawk.
Из-за особенностей работы массивов awk выходные данные, вероятно, не будут в том же порядке, что и исходные данные. Исходный порядок можно сохранить с помощью немного более сложной программы, или вывод можно отсортировать с помощью одной из функций сортировки awk, но, вероятно, более гибким будет использование команды сортировки bash.
При желании этот скрипт awk можно сократить:
awk '{if(!($1 in a)||($2=="ca"))a[$1]=$0};END{for(i in a)print a[i]}' data