【问题标题】:Filter unique lines过滤唯一行
【发布时间】:2017-07-30 04:55:43
【问题描述】:

我有一个名为 fasta 的图块类型,其中包含一个标题“> 12122”,后跟一个字符串。我想删除文件中的重复字符串,只保留一个重复字符串(相同)和相应的标题。
在下面的示例中,AGGTTCGGATAAGTAAGAGCC 是重复的

在:

>17-46151
AGGTTCCGGATAAGTAAGAGCC
>1-242
AGGTTCCGGATAAGTAAGAGCC
>18-41148
TCTTAACCCGGACCAGAAACTA
>43-16054
GTCCCACTCCGTAGATCTGTTC
>32-24116
TAGCATATCGAGCCTGAGAACA
>42-16312
TGATACGGATGTTATACGCAGC

出来:

>1-242
AGGTTCCGGATAAGTAAGAGCC
>18-41148
TCTTAACCCGGACCAGAAACTA
>43-16054
GTCCCACTCCGTAGATCTGTTC
>32-24116
TAGCATATCGAGCCTGAGAACA
>42-16312
TGATACGGATGTTATACGCAGC

【问题讨论】:

  • 你为什么保留18-41148?好像没有重复
  • 抱歉,我想保留唯一的字符串。如果一个重复,我想保留一个重复
  • 您可以尝试使用 Perl 哈希,例如:perl -nE 'chomp;chomp($seq=<>);$seqs{$seq}=$_; END {for (keys %seqs) {say ; say $seqs{$_}}}' in.txt
  • 您尝试了什么,遇到了什么问题?如果您可以向我们展示一些代码,这样我们就可以帮助解决不工作的问题,而不是来到这里并要求我们编写您的代码,这会更好。

标签: perl awk


【解决方案1】:

如果订单是强制性的

# Field are delimited by new line
awk -F "\n" '
   BEGIN { 
      # Record is delimited by ">"
      RS = ">"
      }
   # skip first "record" due to first ">"
   NR > 1 {
      # if string is not know, add it to "Order" list array
      if ( ! (  $2 in L ) ) O[++a] = $2
      # remember (last) peer label/string
      L[$2] = $1
      }
   # after readiong the file
   END{
      # display each (last know) peer based on the order
      for ( i=1; i<=a; i++ ) printf( ">%s\n%s\n", L[O[i]], O[i])
      }
  ' YourFile 

如果订单不是强制性的

awk -F "\n" 'BEGIN{RS=">"}NR>1{L[$2]=$1}END{for (l in L) printf( ">%s\n%s\n", L[l], l)}' YourFile

【讨论】:

    【解决方案2】:
    $ awk '{if(NR%2) p=$0; else a[$0]=p}END{for(i in a)print a[i] ORS i}' file
    >18-41148
    TCTTAACCCGGACCAGAAACTA
    >32-24116
    TAGCATATCGAGCCTGAGAACA
    >1-242
    AGGTTCCGGATAAGTAAGAGCC
    >43-16054
    GTCCCACTCCGTAGATCTGTTC
    >42-16312
    TGATACGGATGTTATACGCAGC
    

    解释:

    {
        if(NR%2)             # every first (of 2) line in p
            p=$0
        else                 # every second line is the hash key
            a[$0]=p
    }
    END{
        for(i in a)          # output every unique key and it's header
            print a[i] ORS i
    }
    

    【讨论】:

      【解决方案3】:

      这是一个快速的单行 awk 解决方案。它应该比其他答案更直接,因为它逐行运行,而不是将数据排队(并循环通过它)直到结束:

      awk 'NR % 2 == 0 && !seen[$0]++ { print last; print } { last = $0 }' file
      

      解释:

      • NR % 2 == 0 仅在偶数记录上运行(行,NR
      • !seen[$0]++ 存储和递增值并仅在 seen[] 哈希中没有值时返回 true(!0 为 1,!1 为 0,!2 为 0,等等)
      • (跳到最后)last 设置为我们完成后每一行的值
      • { print last; print } 将打印last(标题)然后是当前行(基因代码)

      注意:虽然这保留了原始顺序,但它显示了 first 唯一可见的实例,而预期的输出显示了 final 唯一可见的实例:

      >17-46151
      AGGTTCCGGATAAGTAAGAGCC
      >18-41148
      TCTTAACCCGGACCAGAAACTA
      >43-16054
      GTCCCACTCCGTAGATCTGTTC
      >32-24116
      TAGCATATCGAGCCTGAGAACA
      >42-16312
      TGATACGGATGTTATACGCAGC
      

      如果您想要最终唯一看到的实例,您可以在传递给 awk 之前反转文件,然后再将其反转回来:

      tac file |awk … |tac
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-04
        • 1970-01-01
        • 2021-06-08
        • 1970-01-01
        • 1970-01-01
        • 2017-05-16
        • 1970-01-01
        • 2022-12-04
        相关资源
        最近更新 更多