[首先,我要为编辑我的初始帖子道歉。但是在提供代码之后,我就把问题弄得模糊了。
所以,我有一个数组(@start_cod),其中包含用/ n分隔的行,如下所示:
print @start_cod;
tatatattataattatatttat
cacacacaacaccacaac
aaaaaaaaaaaaaaa
我只需要删除换行符,然后在数组的开头添加“>文本”,如下所示:
>text
tatatattataattatatttatcacacacaacaccacaacaaaaaaaaaaaaaaa
我尝试过:
s/\s+\z// for @start_cod;
print ">text@start_cod";
我也尝试过排骨
chomp @start_cod;
print ">text@start_cod";
和
my @start_cod = split("\n",$start_cod);
$start_cod = join("",@start_cod);
print ">text$start_cod";
但我知道
aaaaaaaaaaaaaaaaaaa>textcacacacacaacaccacaac>textaattatatattataattatatttat
关于在Perl编程中如何处理此问题的任何建议?
这是我的代码,可以100%工作。
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
my %alliloux =();
$/="\n>";
while (<>) {
s/>//g;
my ($onoma, @seq) = split (/\n/, $_);
my ($sp, $head) = split (/\./, $onoma);
push @{ $alliloux{$sp} }, join "\n", ">$onoma", @seq;
}
foreach my $sp (keys %alliloux) {
chomp $sp;
my ($head, $dna) = split(/\t/, $sp);
my @start_cod = substr($dna, 3);
say @start_cod;
输入文件:
>name aaaaaaaaaaaaaaaaaa
>name2 acacacacacaacaccacaac
>namex aattatatattataattatatttat
Perl运行后的输出
tatatattataattatatttat
cacacacaacaccacaac
aaaaaaaaaaaaaaa
所需的输出:
>text
tatatattataattatatttatcacacacaacaccacaacaaaaaaaaaaaaaaa
如果我正确理解了您的问题,这应该做您想要的:
use strict;
use warnings;
my @start_cod = (
'aaaaaaaaaaaaaaaaaa',
'acacacacacaacaccacaac',
'aattatatattataattatatttat',
);
print ">text\n", @start_cod, "\n";
[print
首先打印“>文本”和换行符一次,然后在一行上获得@start_cod
项,最后的"\n"
确保在最后一个元素之后有换行符。
输出:
>text
aaaaaaaaaaaaaaaaaaacacacacacaacaccacaacaattatatattataattatatttat
您可能想看Read FASTA into Hash。这是同样的问题,非常接近我在阅读之前编写的代码。另外,还有modules on CPAN that can handle FASTA。
我认为您想合并以相同名称开头的序列,而不考虑数字。序列不应包含内部空格。在代码中,您一直在添加空格。您甚至可以加入换行符。因此,您去看医生,说“我这样做会伤到手臂”,而医生说:“不要这样做。” :)
遇到此类问题时,请在每一步检查操作结果,以查看是否达到预期的效果。这是我认为可以满足您需求的程序的简化版本。我删除了大多数数据结构,因为它们使您的过程变得复杂。
简而言之,请阅读一行并在最后删除换行符。那是换行符的来源之一。然后,提取序列并将其连接到先前的序列。当您用换行符join
时,您将添加换行符。因此,请勿这样做:
use v5.14;
use warnings;
use Data::Dumper;
my %alliloux = ();
while (<DATA>) {
chomp; # get rid of that newline!
s/>//g;
# now split on whitespace, but only up to two parts.
# There's no array here.
my( $name, $seq ) = split /\s+/, $_, 2;
# remove the numbers at the end to get the prefix of the
# name.
my $prefix = $name =~ s/\d+\z//r;
# append the current sequence for this prefix to what we
# have already seen.f
$alliloux{$prefix} .= $seq;
}
say Dumper( \%alliloux );
foreach my $base ( keys %alliloux ) {
say ">text $alliloux{$base}";
}
__DATA__
>name aaa
>name2 cccc
>name99 aattaatt
您不需要中间数组。您可以随时构建字符串。在执行此操作之前,您不需要拥有所有部件。
现在,要找出可能出问题的地方,请立即执行一些操作。确保您已提取正确的内容。可以在要插入的变量周围放置字符,这样您就可以在开头或结尾看到空白:
while (<DATA>) {
chomp; # get rid of that newline!
s/>//g;
my( $name, $seq ) = split /\s+/, $_, 2;
say "Name: <$name>";
say "Seq: <$seq>"
}
然后,添加另一步骤,并确保其有效:
while (<DATA>) {
chomp; # get rid of that newline!
s/>//g;
my( $name, $seq ) = split /\s+/, $_, 2;
say "Name: <$name>";
say "Seq: <$seq>"
my $prefix = $name =~ s/\d+\z//r;
say "Prefix: <$prefix>";
}
对每个步骤重复此过程。然后,当您遇到问题时,您便确定了分歧所在。这是您程序中的相同技术:
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
while (<DATA>) {
s/>//g;
my ($onoma, @seq) = split (/\n/, $_);
say "Onoma: <$onoma>";
}
__DATA__
>name aaa
>name2 cccc
>name99 aattaatt
输出显示@seq
中没有任何内容。您在换行符上进行拆分,但是除非更改了默认行的结尾,否则您只会在末尾得到换行符:
Onoma: <name aaa>
Onoma: <name2 cccc>
Onoma: <name99 aattaatt>
现在@seq
中没有任何内容,因此join "\n", ">$onoma", @seq;
之类的行实际上只是join "\n", ">$onoma"
。稍作检查,您可能已经看到了。
描述缺乏问题的清晰性。
通过查看所需的输出,可以想到以下代码。请查看它是否满足您的要求。
即使查看您的代码,也不清楚您要做什么—代码的某些部分没有多大意义。
use strict;
use warnings;
use feature 'say';
my @start_cod;
while( <DATA> ) {
chomp;
next unless />\s?name.?\s+(.*)/;
push @start_cod, $1;
}
print ">text\n " . join('',@start_cod);
__DATA__
>name aaaaaaaaaaaaaaaaaa
>name2 acacacacacaacaccacaac
.
.
.
> namex aattatatattataattatatttat