根据字符串中的ID删除重复的行

时间:2019-06-05 08:46:17

标签: bash awk sed

我想根据输入行中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 个答案:

答案 0 :(得分:1)

通过GeneID过滤出重复项:

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

详细信息:

  • FS=OFS="\t"-输入/输出字段分隔符
  • f3=$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 :(得分:1)

执行此操作的方式很无聊,而执行此操作的方式则很无聊:

  • sort :根据第二个字符对文件进行唯一排序,其中第二个字符以分号(;)为分隔符:

    $ sort -u -d; -k1,1
    

    此方法具有以下限制:

    • GeneID之前的完整子字符串必须始终相同
    • 它重新排列输出
  • awk :这是另一种无聊的方式。假设-字符和字符是字段分隔符,那么您只需要检查是否已看到字段2:

     $ awk -F'[:;]' '!seen[$2]++'
    
  • awk :这是更有趣的方式。假设您的文件具有以下格式

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

    其中的您知道的:

    • labelkeyvalue是不包含':'或';'
    • 的任何字符串
    • 键值对不需要以相同的顺序出现。即key2中的label1可能是key1中的label2

    这里的技巧是提取您感兴趣的密钥:

    awk -v key="GeneID" '{ match($0,key ":[^:;]*");
                           value=substr($0,RSTART,RLENGTH)
                         }
                         !seen[value]++' file
    

答案 2 :(得分:0)

我建议使用自定义字段分隔符:

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

[[:space:]:;]+模式匹配一​​个或多个(+)空格([:space:]),;:字符。该ID现在位于字段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

请参见online demo