我想读取一个文件,并根据它有多少链(M,N,O,..)来生成一些数组。
以下是文件的一部分:
SEQRES 1 M 312 ALA ALA ASP PRO LYS LEU LEU LYS ALA ALA ALA GLU ALA
SEQRES 2 M 312 SER TYR ALA PHE ALA LYS GLU VAL ASP TRP ASN ASN GLY
SEQRES 3 M 312 ILE PHE LEU GLN ALA PRO GLY LYS LEU GLN PRO LEU GLU
SEQRES 4 M 312 ALA LEU LYS ALA ILE ASP LYS MET ILE VAL MET GLY ALA
SEQRES 5 M 213 SER PHE ASN ARG ASN
SEQRES 1 N 312 ASP GLU ILE GLY ASP ALA ALA LYS LYS LEU GLY ASP ALA
SEQRES 2 N 312 SER TYR ALA PHE ALA LYS GLU VAL ASP TRP ASN ASN GLY
SEQRES 3 N 312 ILE PHE LEU GLN ALA PRO GLY LYS LEU GLN PRO LEU GLU
SEQRES 4 N 312 ALA LEU LYS ALA ILE ASP LYS MET ILE VAL MET GLY ALA
SEQRES 5 N 312 ALA ALA ASP PRO LYS LEU LEU LYS ALA ALA ALA GLU ALA
SEQRES 6 N 312 VAL THR SER ARG ALA ASP TRP ASP ASN VAL
SEQRES 1 O 312 HIS HIS LYS ALA ILE GLY SER ILE SER GLY PRO ASN GLY
SEQRES 2 O 312 SER TYR ALA PHE ALA LYS GLU VAL ASP TRP ASN ASN GLY
SEQRES 3 O 312 ILE PHE LEU GLN ALA PRO GLY LYS LEU GLN PRO LEU GLU
SEQRES 4 O 312 ALA LEU LYS ALA ILE ASP LYS MET ILE VAL
这是我的代码:
my @seq;
my $string="";
my @seqFile;
my $file=<>;
open(FILE, "$file");
while (my $line=<FILE>){
if ($line =~ /^SEQRES/) {
chomp $line;
push @seq, [split (/\s+/, $line)] ;
}
}
close(FILE);
for my $i (0..$#seq) {
my $ob =$seq[$i][2];
if ($seq[$i][2] eq $ob ){
for (my $j=4;$j<=$#{$seq[$i]};$j++) {
my $temp= $seq[$i][$j];
$string .= $temp;
}
$ob = $seq[$i][2];
last;
}
push @seqFile, $ob;
push @seqFile, $string;
$string = ''; #string needs to be empty to store new lines
}
使用上面的示例:3个数组M(:) ALAALAASP:....,N(:) ASPGLU ..,O(:) HISHISLYS ......
我设法将所有SEQRES放在一个字符串中,但这不是我想要的。
某处我需要设置if(){}
并检查M <=> N
和N <=> O
是不同的。然后保存字符串并启动字符串和数组。但它不断累积与$#seq相同字符串的次数。或者,如果我移动一个}
的位置,那么它不存储任何内容,或者给我错误消息。我怎么能这样做?
答案 0 :(得分:2)
你在这里看不到问题吗?
my $ob =$seq[$i][2];
if ($seq[$i][2] ne $ob ){
这类似于:
my $x = "this";
if ($x ne "this) {
if
条件怎么可能是真的?
更好的方法是使用数组哈希,键入M,N或O,(你设置的是$ ob):
open (my $fh, '<', $file); # using global globs like FILE is depreciated
my %hash_of_arrays;
while (<$fh>) {
my @data = split;
push @{$hash_of_arrays{$data[2]}}, join('', (@data)[4..$#data]);
}
很确定这与你想要做的很接近; push
的第二个arg使用数组切片。
请注意,如果@{$hash{$data[2]}}
尚不存在,则会通过 autovivification 创建:http://en.wikipedia.org/wiki/Autovivification
答案 1 :(得分:1)
我认为这个程序可以满足您的需求。
我没有看第三个字段值的变化,而是写了一个空白行或文件末尾标记链的末尾。
use strict;
use warnings;
my $file = 'seq.txt';
open my $fh, '<', $file or die $!;
my @seqFile;
my $string;
my $ob;
while (<$fh>) {
if (/^SEQRES/) {
my @data = split;
$string .= join '', @data[4..$#data];
$ob = $data[2];
}
if (eof($fh) or not /\S/) {
push @seqFile, $ob, $string;
$ob = $string = undef;
}
}
use Data::Dumper;
print Dumper \@seqFile;
<强>输出强>
$VAR1 = [
'M',
'ALAALAASPPROLYSLEULEULYSALAALAALAGLUALASERTYRALAPHEALALYSGLUVALASPTRPASNASNGLYILEPHELEUGLNALAPROGLYLYSLEUGLNPROLEUGLUALALEULYSALAILEASPLYSMETILEVALMETGLYALASERPHEASNARGASN',
'N',
'ASPGLUILEGLYASPALAALALYSLYSLEUGLYASPALASERTYRALAPHEALALYSGLUVALASPTRPASNASNGLYILEPHELEUGLNALAPROGLYLYSLEUGLNPROLEUGLUALALEULYSALAILEASPLYSMETILEVALMETGLYALAALAALAASPPROLYSLEULEULYSALAALAALAGLUALAVALTHRSERARGALAASPTRPASPASNVAL',
'O',
'HISHISLYSALAILEGLYSERILESERGLYPROASNGLYSERTYRALAPHEALALYSGLUVALASPTRPASNASNGLYILEPHELEUGLNALAPROGLYLYSLEUGLNPROLEUGLUALALEULYSALAILEASPLYSMETILEVAL'
];
修改强>
既然我知道数据文件没有空行来描绘链条,我的原始解决方案将无效。
此备选方案检查记录的第二个字段中的序列号,并在该数字为1时启动新链。每当新链开始时,也必须保存累积链,并且也可以在文件结束后保存。读循环退出。
此程序的输出与上面显示的相同。
use strict;
use warnings;
my $file = 'seq.txt';
open my $fh, '<', $file or die $!;
my @seqFile;
my $chain;
my $ob;
while (<$fh>) {
next unless /^SEQRES/;
my @data = split;
if ($data[1] == 1) {
push @seqFile, $ob, $chain if $chain;
$ob = $chain = undef;
}
$chain .= join '', @data[4..$#data];
$ob = $data[2];
}
push @seqFile, $ob, $chain if $chain;
use Data::Dumper;
print Dumper \@seqFile;