удалить дублированные строки на основе идентификатора в строке - PullRequest
1 голос
/ 05 июня 2019

Я хотел бы удалить дубликаты (и сохранить только первый дубликат) на основе числа, следующего за GeneID: в строках моего ввода. Я только знаю, как фильтровать по столбцу: awk '!seen[$3]++', но здесь это не работает.

Ввод (табуляция разделена):

 Gene1 mRNA ID=rna74353;Parent=gene38534;Dbxref=GeneID:109200613;Genbank:XM_019356191.2,Genbank:XM_025904163.1
 Gene2 mRNA ID=rna74354;Parent=gene38534;Dbxref=GeneID:109200613;Genbank:XM_019356192.2,Genbank:XM_025904163.2
 Gene3 mRNA ID=rna74355;Parent=gene38534;Dbxref=GeneID:109200614;Genbank:XM_019356193.2,Genbank:XM_025904163.3
 Gene4 mRNA ID=rna74356;Parent=gene38534;Dbxref=GeneID:109200615;Genbank:XM_019356194.2,Genbank:XM_025904163.4

из

 Gene1 mRNA ID=rna74353;Parent=gene38534;Dbxref=GeneID:109200613;Genbank:XM_019356191.2,Genbank:XM_025904163.1
 Gene3 mRNA ID=rna74355;Parent=gene38534;Dbxref=GeneID:109200614;Genbank:XM_019356193.2,Genbank:XM_025904163.3
 Gene4 mRNA ID=rna7435;Parent=gene38534;Dbxref=GeneID:109200615;Genbank:XM_019356194.2,Genbank:XM_025904163.4

Ответы [ 3 ]

1 голос
/ 05 июня 2019

Фильтрация дубликатов по GeneID:

$ awk 'BEGIN{ FS=OFS="\t" }{ f3=$3; sub(";.*", "", f3) }!a[f3]++' test.txt

Детали:

  • FS=OFS="\t" - разделитель полей ввода / вывода
  • f3=$3 - скопировать значение 3-го поля в переменную f3
  • sub(";.*", "", f3) - удалить все символы, следующие за ; из значения f3 (чтобы получить только номер GeneID с префиксом)
  • !a[f3]++ - распечатать запись об уникальном вхождении критической переменной f3

Выход:

Gene1   mRNA    GeneID:109200613;Genbank:XM_019356191.2
Gene1   mRNA    GeneID:109200614;Genbank:XM_019356193.2
Gene1   mRNA    GeneID:109200615;Genbank:XM_019356193.2
1 голос
/ 05 июня 2019

Существует скучный способ сделать это и менее скучный способ сделать это:

  • sort: уникально отсортировать файл на основе второгостолбец, где-character (;) является разделителем:

    $ sort -u -d; -k1,1
    

    Этот метод имеет следующие ограничения:

    • полная подстрока перед GeneID всегда должна быть идентичной
    • переупорядочивает вывод
  • awk: это еще один скучный способ.Предположим, что-character и символ являются разделителями полей, тогда вам нужно только проверить, видели ли вы поле 2:

     $ awk -F'[:;]' '!seen[$2]++'
    
  • awk: этоэто более интересный способ.Предположим, что ваш файл имеет следующий формат

    label1 key1:value1;key2:value2;key3:value3
    label2 key1:value1;key2:value2;key3:value3
    

    , из которого вы знаете, что:

    • label, key и value - любая строка, которая не содержит ': 'or'; '
    • пары ключ-значение не обязательно должны появляться в одном и том же порядке.Т.е. key2 из label1 может быть key1 из label2.

    Хитрость заключается в том, чтобы извлечь интересующий вас ключ:

    awk -v key="GeneID" '{ match($0,key ":[^:;]*");
                           value=substr($0,RSTART,RLENGTH)
                         }
                         !seen[value]++' file
    
0 голосов
/ 05 июня 2019

Я предлагаю использовать пользовательский разделитель полей:

awk -F'[[:space:]:;]+' '!seen[$4]++' file > newfile

Шаблон [[:space:]:;]+ соответствует одному или нескольким (+) пробелам ([:space:]), ; или : символам.Идентификатор находится в поле 4, поэтому используется '!seen[$4]++'.

Вывод:

Gene1   mRNA    GeneID:109200613;Genbank:XM_019356191.2
Gene3   mRNA    GeneID:109200614;Genbank:XM_019356193.2
Gene4   mRNA    GeneID:109200615;Genbank:XM_019356193.2

См. онлайн-демонстрацию .

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