Python 基于多个文件作为参考的文件上的字符串替换
[寻找最好使用UNIX工具的解决方案,但Python也可以] 我有三个文件,第一个文件包含名为“headers”(以>)的字符串,后跟一行字符,第二个文件包含ID和名称,第三个文件包含许多列,包括第一个文件的头($1),第二个文件的ID($3)以及我想添加到第一个文件字符串中的一些相关属性,如下例所示: 文件1)数据(带有序列数据的fasta文件) 文件2)ID和名称Python 基于多个文件作为参考的文件上的字符串替换,python,shell,unix,awk,fasta,Python,Shell,Unix,Awk,Fasta,[寻找最好使用UNIX工具的解决方案,但Python也可以] 我有三个文件,第一个文件包含名为“headers”(以>)的字符串,后跟一行字符,第二个文件包含ID和名称,第三个文件包含许多列,包括第一个文件的头($1),第二个文件的ID($3)以及我想添加到第一个文件字符串中的一些相关属性,如下例所示: 文件1)数据(带有序列数据的fasta文件) 文件2)ID和名称 >[ID1] [Name1] >[ID2] [Name2] >[ID3] [Name3] 文件3)交叉引用表
>[ID1] [Name1]
>[ID2] [Name2]
>[ID3] [Name3]
文件3)交叉引用表-包含13个字段的文件(字段6-11无关紧要)
我需要用一个新字符串替换第一个文件上的“header”字符串,该字符串由使用第三个文件和第三个文件的多个字段交叉引用的名称(第二个文件)组成
我需要的是查看文件3(交叉引用表),查看第一个字段(标题),然后存储其他值。使用第三个字段(数字)的值,在file2(id和Name)上查找适当的名称并存储它,然后简单地重写file1,用一个新字符串更改存储的头,该字符串由交叉引用表上的所有相关字段组成,加上file2中的名称
我目前的做法如下:
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
文件2)
File3)[此处的所有行将匹配File1中的标题和File2中的行)
输出:
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的序列)保持不变。文件2中与文件3上的任何ID不匹配的行将被忽略。文件1上的所有标题将显示在文件3上,即使文件2上的所有“ID”都不匹配。好吧……具有名为
1
的文件,其内容如下:
>This_is_my_header_number_1
TCGTACGTCACTAATCGAG
>And_here_is_number_2
TCAGCAGTCATCATACTGCGTA
>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
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
以及名为2
的文件,其内容如下:
>This_is_my_header_number_1
TCGTACGTCACTAATCGAG
>And_here_is_number_2
TCAGCAGTCATCATACTGCGTA
>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
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
以及名为3
的文件,其内容如下:
>This_is_my_header_number_1
TCGTACGTCACTAATCGAG
>And_here_is_number_2
TCAGCAGTCATCATACTGCGTA
>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
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
这里发生了什么
- 我获取文件2并删除前导的
符号 - 然后我拿文件3
- 然后我对文件2(第一列)和文件3(第三列ID)进行排序
- 然后我将第3列(ID)上的文件3与文件2中的第一列连接起来 (ID)
- 然后我将字段转换为字符串
- 然后,我为每个需要替换的头生成sed-substitute命令,该命令类似于
s@;
- 运行sed时,我在文件
上使用生成的参数替换标题1
- 使用
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个块语句
前两个块分别用file1
和file2
的内容填充数组a
和b
最后一个块通过查找数组打印到预期行
请注意,文件之间的切换是与
NR==FNR
一起完成的,以匹配第一个文件和变量n
,该变量对于file2
未设置,对于file3
设置为1
,请在您的帖子中也发布预期的输出样本。@RavinderSingh13刚刚根据要求添加了它,谢谢。请求请使用小样本更新输入/输出样本(无论如何,小样本或更长样本的逻辑相同),以便我们更好地理解它。File3使用“,”作为分隔符,还是使用空格作为分隔符?