基于多个文件作为参考

时间:2018-06-15 07:10:56

标签: python shell unix awk fasta

[寻找最好使用UNIX工具的解决方案,但Python也能正常工作]

我有三个文件,其中第一个将包含名为'headers'的字符串(以>开头),后跟带字符的行,第二个将包含ID和名称,第三个将包含许多列,包括标题从第一个文件($ 1),第二个文件上的ID($ 3)以及我想要添加到第一个文件的字符串的一些相关属性,如下例所示:

File1)数据(带序列数据的fasta文件)

>[Header1]
ATCGATCGATCG
>[Header2]
CGGTAAGCTAGCTAG
>[Header3]
TCTGTACTGCATGCA
...

File2)ID和名称

>[ID1] [Name1]
>[ID2] [Name2]
>[ID3] [Name3]

File3)交叉引用表 - 包含13个字段的文件(字段6-11无关紧要)

[Header],"[Size];",[ID],[PRCNT],[AL],[6],[7],[8],[9],[10],[11],[EVAL],[SCORE]

我需要将第一个文件中的'header'字符串替换为新字符串,该字符串由使用第3个文件和第3个文件的多个字段进行交叉引用的名称(第2个文件)组成。

我需要的是查看file3(Crossreference表),查看第一个字段(Header),然后存储其他值。使用第三个字段(Number)的值,在file2(ID和名称)上查找相应的Name并存储它,然后只需重写file1,用一个新字符串更改存储的Header,该字符串由所有相关字段组成。交叉引用表,加上File2中的Name 我目前正在这样做的方式如下:

counter=1
while read Header Size ID PRCNT AL F6 F7 F8 F9 F10 F11 EVAL SCORE; do
    name=`grep ^">$ID" File2`
    newheader=">$counter|PRCNT_$PRCNT|AL_$AL|eval_$EVAL|score_$SCORE|Size_${Size%;}|$name"
    echo -en "\r"; echo -en "Renaming headers ($counter/$totalnumber)   "
    sed -i "s#^>$Header#$newheader#" File1
    ((counter+=1))
done < File3

这样,我将[Header]替换为{unique_number}|PRCNT_{field4_file3}|AL_{field5_file3}|eval_{field12_file3}|score_{field13_file3}|Size_{field2_file3-removing_';'}|{full_line_file2}

它正常工作,因为我需要它才能工作,除了它需要很长时间才能运行(因为我有数千个'标题'),我确信必须有一个更简单(更快)的方法来完成它,除了我不知道会是哪种方式......

我需要的是一种处理所有三个文件的简单方法,一个包含带有标题的数据,一个具有正确名称的文件和一个交叉引用它们(并具有它们的所有属性),然后重新打印固定的数据文件 标题(显示正确的名称和所有相关属性)。

我更喜欢使用UNIX工具(sed,awk,grep等)的解决方案,但python也可以。

提前致谢。

编辑:按要求添加样本输入/输出

File1中)

>This_is_my_header_number_1
TCGTACGTCACTAATCGAG
>And_here_is_number_2
TCAGCAGTCATCATACTGCGTA

文件2)

>19846 Proper name foo bar faa 124;k__name
>949 A name that does not appear on either other file
>24728 Name foo nonrelated la;k__laa

File3)[此处的所有行都将与File1中的标题和File2中的行匹配)

This_is_my_header_number_1  103;    19846   0.83    502 foo faa bar 849 97510   1111    5e-10   1005
And_here_is_number_2    44; 24728   0.98    301 wol olo fii 235 889 9123    2e-20   3045

输出:

1|PRCNT_0.83|AL_502|eval_5e-10|score_1005|Size_103|>19846 Proper name foo bar faa 124;k__name
TCGTACGTCACTAATCGAG
2|PRCNT_0.98|AL_301|eval_2e-20|score_3045|Size_44|>24728 Name foo nonrelated la;k__laa
TCAGCAGTCATCATACTGCGTA

请注意,标题已被替换,但标题下的行(A,T,C和Gs的序列)保持不变。 file2中与File3上的任何ID都不匹配的行将被忽略。 file1上的所有标题都将出现在File3上,即使文件2上的所有“ID”都没有。

2 个答案:

答案 0 :(得分:0)

嗯......
拥有一个名为1的文件,内容为:

>This_is_my_header_number_1
TCGTACGTCACTAATCGAG
>And_here_is_number_2
TCAGCAGTCATCATACTGCGTA

以及名为2的文件,内容为:

>19846 Proper name foo bar faa 124;k__name
>949 A name that does not appear on either other file
>24728 Name foo nonrelated la;k__laa

以及名为3的文件,内容为:

This_is_my_header_number_1  103;    19846   0.83    502 foo faa bar 849 97510   1111    5e-10   1005
And_here_is_number_2    44; 24728   0.98    301 wol olo fii 235 889 9123    2e-20   3045

运行以下命令:

sed "$(
        sed 's/^>//' 2 | sort \
        | join -13 -21 <(sort -k3 3) - \
        | sed \
's#\([^ ]*\) \(.*\)_\([0-9]*\) \([^ ]*\); \([^ ]*\) \([^ ]*\) [^ ]* [^ ]* [^ ]* [^ ]* [^ ]* [^ ]* \([^ ]*\) \([^ ]*\) \(.*\)#'\
'\2_\3 \3|PRCNT_\5|AL_\6|eval_\7|score_\8|Size_\4|>\1 \9#;'\
's/\([^ ]*\) \(.*\)/s@>\1@\2@;/'
)" <1

产生以下输出:

1|PRCNT_0.83|AL_502|eval_5e-10|score_1005|Size_103|>19846 Proper name foo bar faa 124;k__name
TCGTACGTCACTAATCGAG
2|PRCNT_0.98|AL_301|eval_2e-20|score_3045|Size_44|>24728 Name foo nonrelated la;k__laa]
TCAGCAGTCATCATACTGCGTA

这里发生了什么?

  • 我取文件2并删除前导>
  • 然后我拿文件3
  • 然后我排序文件2(在第一列)并在第3列(ID)上排序文件3
  • 然后我将第3列(ID)上的文件3与文件2中的第一列连接起来 (ID)
  • 然后我将字段转换为字符串<header> <the line that should be substituded for header, that looks as fancy as you specified>
  • 然后我为每个需要替换的标题生成看起来像s@<header>@<the line that should be substituded for header>@;的sed替换命令。
  • 我运行sed,文件1上生成的参数替换为header。

答案 1 :(得分:0)

使用awk

awk -v RS='>' '
   NR==FNR{
     a[$1]=$2
     next
   }
   !n{
     b[substr($1,2)]=substr($0,index($0," ")+1)
     next
   }
   n==1{
     print FNR,"PRCNT_"$4,"AL_"$5,"eval_"$12,"score_"$13,"Size_"$2,">"$3" "b[$3]
     print a[$1] 
   }' file1 RS='\n' file2 n=1  OFS='|' file3

与解析这3个文件相关联的3个块语句。

前两个块分别填充数组ab,内容为file1file2

通过查看数组,最后一个块打印出预期的行。

请注意,文件之间的切换与NR==FNR一起完成,以匹配第一个文件和n未设置的变量file2,并设置为1 file3