我正在处理.fasta文件的标题(这是一个普遍用于遗传学/生物信息学的文件,用于存储DNA / RNA序列数据)。 Fasta文件的标题以>开头符号(提供特定信息),然后是标题描述的下一行的实际序列数据。序列数据无限延伸,直到下一个\ n之后跟随下一个标题及其各自的序列。例如:
>scaffold1.1_size947603
ACGCTCGATCGTACCAGACTCAGCATGCATGACTGCATGCATGCATGCATCATCTGACTGATG....
>scaffold2.1_size747567.2.603063_605944
AGCTCTGATCGTCGAAATGCGCGCTCGCTAGCTCGATCGATCGATCGATCGACTCAGACCTCA....
依旧......
所以,我与我正在使用的生物体的基因组的fasta标题有问题。不幸的是,解决这个问题所需的perl专业知识似乎超出了我目前的技能水平:S所以我希望有人可以告诉我如何做到这一点。
我的基因组由大约25000个fasta标题及其各自的序列组成,当前状态的标题给我带来了很多我正在尝试使用的序列对齐器的麻烦,所以我必须大大简化它们。以下是我的前几个标题的示例:
>scaffold1.1_size947603
>scaffold10.1_size550551
>scaffold100.1_size305125:1-38034
>scaffold100.1_size305125:38147-38987
>scaffold100.1_size305125:38995-44965
>scaffold100.1_size305125:76102-78738
>scaffold100.1_size305125:84171-87568
>scaffold100.1_size305125:87574-89457
>scaffold100.1_size305125:90495-305068
>scaffold1000.1_size94939
基本上我想将这些看起来像这样:
>scaffold1.1a
>scaffold10.1a
>scaffold100.1a
>scaffold100.1b
>scaffold100.1c
>scaffold100.1d
>scaffold100.1e
>scaffold100.1f
>scaffold100.1g
>scaffold1000.1a
或许甚至可能(但这看起来会更复杂):
>scaffold1.1
>scaffold10.1
>scaffold100.1a
>scaffold100.1b
>scaffold100.1c
>scaffold100.1d
>scaffold100.1e
>scaffold100.1f
>scaffold100.1g
>scaffold1000.1
我在这里做的是摆脱基因组每个支架的所有大小数据。对于碰巧碎裂的支架,我想用a,b,c,d等表示它们。有一些支架有超过26个碎片所以也许我可以用x,y,z,A表示它们, B,C,D ....等..
我正在考虑使用类似于此的简单替换foreach循环来执行此操作:
#!/usr/bin/perl -w
### Open the files
$gen = './Hc_genome/haemonchus_V1.fa';
open(FASTAFILE, $gen);
@lines = <FASTAFILE>;
#print @lines;
###Add an @ symbol to the start of the label
my @refined;
foreach my $lines (@lines){
chomp $lines;
$lines =~ s/match everything after .1/replace it with a, b, c.. etc/g;
push @refined, $lines;
}
#print @refined;
###Push the array on to a new fasta file
open FILE3, "> ./Hc_genome/modded_haemonchus_V1.fa" or die "Cannot open output.txt: $!";
foreach (@refined)
{
print FILE3 "$_\n"; # Print each entry in our array to the file
}
close FILE3;
但我不知道必须在匹配和替换运算符中的$ 1和\ n之间添加添加的字母标签。基本上是因为我不确定如何按顺序通过字母表为特定脚手架的每个片段(我可以管理的是在每个片段的开头添加a ...)
如果您不介意,请告诉我如何实现这一目标!
非常感谢!
安德鲁
答案 0 :(得分:2)
在Perl中,增量运算符++
对字符串有“神奇”的行为。例如。 my $s = "a"; $a++
将$a
增加到"b"
。这一直持续到"z"
,其中增量将产生"aa"
,依此类推。
您文件的标题似乎已正确排序,因此我们可以遍历每个标题。从标题中,我们提取起始部分(一切都包括.1
)。如果此起始部分与前一个标题的起始部分相同,则我们递增序列标识符。否则,我们将其设置为"a"
:
use strict; use warnings; # start every script with these
my $index = "a";
my $prev = "";
# iterate over all lines (rather than reading all 25E3 into memory at once)
while (<>) {
# pass through non-header lines
unless (/^>/) {
print; # comment this line to remove non-header lines
next;
}
s/\.1\K.*//s; # remove everything after ".1". Implies chomping
# reset or increment $index
if ($_ eq $prev) {
$index++;
} else {
$index = "a";
}
# update the previous line
$prev = $_;
# output new header
print "$_$index\n";
}
用法:$ perl script.pl <./Hc_genome/haemonchus_V1.fa >./Hc_genome/modded_haemonchus_V1.fa
。
编写接受STDIN输入并写入STDOUT的程序被认为是一种很好的风格,因为这样可以提高灵活性。不要在perl脚本中对路径进行硬编码,而是保持脚本的通用性,并使用<
之类的shell重定向运算符来指定输入。这也可以省去手动打开文件的麻烦。
示例输出:
>scaffold1.1a
>scaffold10.1a
>scaffold100.1a
>scaffold100.1b
>scaffold100.1c
>scaffold100.1d
>scaffold100.1e
>scaffold100.1f
>scaffold100.1g
>scaffold1000.1a