如何提取出现在同一文本文件中不同行上的多个信息位


8

我正在尝试提取同一文本文件内不同行上出现的序列ID和簇号。

输入看起来像

>Cluster 72
0   319aa, >O311_01007... *
>Cluster 73
0   318aa, >1494_00753... *
1   318aa, >1621_00002... at 99.69%
2   318aa, >1622_00575... at 99.37%
3   318aa, >1633_00422... at 99.37%
4   318aa, >O136_00307... at 99.69%
>Cluster 74
0   318aa, >O139_01028... *
1   318aa, >O142_00961... at 99.69%
>Cluster 75
0   318aa, >O300_00856... *

所需的输出是一列中的序列ID,第二列中是相应的簇号。

>O311_01007  72
>1494_00753  73
>1621_00002  73
>1622_00575  73
>1633_00422  73
>O136_00307  73
>O139_01028  74
>O142_00961  74
>O300_00856  75

有人能帮忙吗?


序列ID始终是不是以3d开头的行上的3d空格字段>吗?另外,您可能对我们的姊妹网站Bioinformatics感兴趣。
terdon

Answers:


13

使用awk:

awk -F '[. ]*' 'NF == 2 {id = $2; next} {print $3, id}' input-file
  • 我们用 -F '[. ]*'
  • 包含两个字段的>Cluster行(行),将第二个字段另存为ID并移至下一行
  • 与其他行一起,打印第三个字段和保存的ID

与其确定字段的数量,不如根据字段中的其他内容,显式查找$1 == ">Cluster"而不是,可能会更好NF == 2
蒙蒂·哈德

5

您可以awk为此使用:

awk '/>Cluster/{
      c=$2;
      next
    }{
      print substr($3,2,length($3)-4), c
    }' file

第一个block语句正在捕获群集ID。第二个语句块(默认语句)是提取所需数据并打印。


您无需将" "用作参数print。只需使用逗号分隔参数,它将使用OFS(默认空间)分隔参数。
muru

4

这是将Ruby作为单行代码的替代方案:

ruby -ne 'case $_; when /^>Cluster (\d+)/;id = $1;when /, (>\w{4}_\w{5})\.\.\./;puts "#{$1} #{id}";end' input_file

或分散在多行上:

ruby -ne 'case $_
when /^>Cluster (\d+)/
  id = $1
when /, (>\w{4}_\w{5})\.\.\./
  puts "#{$1} #{id}"
end' input_file

我想awk如果您了解Ruby和regexen,它的可读性仅比该版本高。值得一提的是,此代码可能会比简单地分割行更健壮,因为它会查找周围的文本。


1

Perl:

$ perl -ne 'if(/^>.*?(\d+)/){$n=$1;}else{ s/.*(>[^.]+).*/$1 $n/; print}' file 
>O311_01007 72
>1494_00753 73
>1621_00002 73
>1622_00575 73
>1633_00422 73
>O136_00307 73
>O139_01028 74
>O142_00961 74
>O300_00856 75

说明

  • perl -ne:逐行(-n)读取输入文件,并将给出的脚本-e应用于每行。
  • if(/^>.*?(\d+)/){$n=$1;}:如果此行以a开头,请在该行>的末尾找到最长的数字,并将其另存为$n
  • else{ s/.*(>[^.]+).*/$1 $n/; print:如果该行不是以开头>,则将所有内容替换.>>[^.]+)后最长的非字符段,即序列名称($1因为我们已经捕获了正则表达式匹配项)和当前值$n

或者,使用更像awk的方法:

$ perl -lane 'if($#F==1){$n=$F[1]}else{$F[2]=~s/\.+$//; print "$F[2] $n"}' file 
>O311_01007 72
>1494_00753 73
>1621_00002 73
>1622_00575 73
>1633_00422 73
>O136_00307 73
>O139_01028 74
>O142_00961 74
>O300_00856 75

这只是与各种awk方法相同的基本思想的繁琐方式。我出于完整和Perl爱好者的考虑而将其包括在内。如果您需要解释,请使用awk解决方案:)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.