问题描述
我正在尝试使用以下行来转换文件1(如果有生物信息学家通过,则为gtf文件):
1 X exon 1 300000 1000 - . gene_id "Z.633"; transcript_id "Z.633.mrna1"; exon_number "1";
1 X transcript 1 300000 1000 - . gene_id "Z.633"; transcript_id "Z.633.mrna1";
1 X exon 300005 300500 1000 - . gene_id "Y.6330"; transcript_id "Y.6330.mrna1"; exon_number "2";
1 X exon 300500 310000 1000 + . gene_id "Y.6330"; transcript_id "Y.6330.mrna1"; exon_number "1";
1 X transcript 30005 310000 1000 + . gene_id "Y.6330"; transcript_id "Y.6330.mrna1";
到一个文件中,所有“ Z”将被“ F”和其他对应关系替换。所有对应关系都在我用作字典的文件2中,第1列是键,第2列是值。
示例文件2:
Z.633 F.633
Y.6330 U.6330
示例结果:
1 X exon 1 300000 1000 - . gene_id "F.633"; transcript_id "F.633.mrna1"; exon_number "1";
1 X transcript 1 300000 1000 - . gene_id "F.633"; transcript_id "F.633.mrna1";
1 X exon 300005 300500 1000 - . gene_id "U.6330"; transcript_id "U.6330.mrna1"; exon_number "2";
1 X exon 300500 310000 1000 + . gene_id "U.6330"; transcript_id "U.6330.mrna1"; exon_number "1";
1 X transcript 30005 310000 1000 + . gene_id "U.6330"; transcript_id "U.6330.mrna1";
file1大约有200000行,而file2则有20000行。
为此,我使用了awk脚本:
NR == FNR {
rep[ $2 ] = $1
next
}
{
for (key in rep)
gsub(key,rep[key])
print
}
然后:
awk -f dict.awk file2 file1 > newfile
我的问题是脚本实际上运行了好几天...有什么办法可以改善它? 有没有更适合此问题的编程语言? (我尝试使用python,但是运行时间更糟)
(使用的脚本python:)
def replaceWithDictionnary(dictFileName,filetoReplaceName,newFileName):
import re
with open(dictFileName,'r') as d:
dictFile = dict((line.strip().split())[::-1] for line in d)
with open(newFileName,'w') as g:
with open(filetoReplaceName,'r') as f:
for line in f.readlines():
for d_key,d_value in dictFile.items():
if bool(re.search(d_key+"\D+",line)):
#if "\""+d_key+"\"" in line:
#print(d_key)
newline=line.replace(d_key,d_value)
#print(d_value)
g.write(newline)
continue
我可以说不是花了那么长时间的词典部分,因为我用一个较小的file1测试了它,并且运行很快...
解决方法
假设每条记录仅替换一个gene_id
,并且总是可以在第10列中找到它,就像在示例文件中一样,您可以找到它并调用gsub
一次,而不是每条记录调用20K函数。
> cat tst.awk
NR==FNR {
r[$1] = $2
next
}
{
x = $10
gsub(/"|;/,"",x)
gsub(x,r[x])
print
}
awk -f tst.awk file2 file1