[寻找最好使用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”都没有。
答案 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
这里发生了什么?
>
。<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替换命令。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个块语句。
前两个块分别填充数组a
和b
,内容为file1
和file2
。
通过查看数组,最后一个块打印出预期的行。
请注意,文件之间的切换与NR==FNR
一起完成,以匹配第一个文件和n
未设置的变量file2
,并设置为1
file3
。