如何使用Perl按顺序读取文件?

时间:2014-10-16 01:42:04

标签: perl

我有以下代码。它工作正常,但输出与输入文件的顺序不同。例如我在输入的FASTA文件中有一个蛋白质列表。我的输出文件运行我的代码很好,但蛋白质的顺序似乎是随机的。

我错过了什么?

#!/usr/bin/perl
#usage: perl seqComp.pl <input_fasta_file> > <output_file>

use strict;

open( S, "$ARGV[0]" ) || die "cannot open FASTA file to read: $!";

my %s;      # a hash of arrays, to hold each line of sequence
my %seq;    #a hash to hold the AA sequences.
my $key;

while (<S>) {    #Read the FASTA file.
    chomp;
    if (/>/) {
        s/>//;
        $key = $_;
    } else {
        push( @{ $s{$key} }, $_ );
    }
}

foreach my $a ( keys %s ) {
    my $s = join( "", @{ $s{$a} } );
    $seq{$a} = $s;
    #print("$a\t$s\n");
}

my @aa = qw(A R N D C Q E G H I L K M F P S T W Y V);
my $aa = join( "\t", @aa );
#print ("Sequence\t$aa\n");

foreach my $k ( keys %seq ) {
    my %count;    # a hash to hold the count for each amino acid in the protein
    my @seq = split( //, $seq{$k} );
    foreach my $r (@seq) {
        $count{$r}++;
    }
    my @row;
    push( @row, ">" . $k );
    foreach my $a (@aa) {
        $count{$a} ||= 0;
        my $percentAA = sprintf( "%0.2f", $count{$a} / length( $seq{$k} ) );
        push( @row,
            $a . ":" . $count{$a} . "/" . length( $seq{$k} ) . "=" . sprintf( "%0.0f", $percentAA * 100 ) . "%" );
        $count{$a} = sprintf( "%0.2f", $count{$a} / length( $seq{$k} ) );

        # push(@row,$count{$a});
    }
    my $row = join( "\t\n", @row );
    print("$row\n\n");
}

3 个答案:

答案 0 :(得分:0)

hash之类的%seq没有特定的订单。

答案 1 :(得分:0)

数组保持顺序,哈希是随机顺序。如果要保留顺序,可以将键推送到数组中,但只有在哈希中不存在键或者重复时才执行此操作。

for(<S>) {
  my ($key,$value) = &parse($_);
  push @keys, $key unless exists $hash{$key};
  $hash{$key} = $value;
}

for my $key (@keys) {
  my $value = $hash{$key};

  ...
}

答案 2 :(得分:0)

如果订单很重要,请不要使用哈希。

相反,我建议使用如下数组的数组:

#!/usr/bin/perl
#usage: perl seqComp.pl <input_fasta_file> > <output_file>
use strict;
use warnings;
use autodie;

my $file = shift or die "Usage: perl $0 <input_fasta_file> > <output_file>";
open my $fh, '<', $file;

my @fasta;

while (<$fh>) {    #Read the FASTA file.
    chomp;
    if (/>/) {
        push @fasta, [ $_, '' ];
    } else {
        $fasta[-1][1] .= $_;
    }
}

my @aa = qw(A R N D C Q E G H I L K M F P S T W Y V);

for (@fasta) {
    my ( $k, $seq ) = @$_;

    print "$k\n";

    my %count;    # a hash to hold the count for each amino acid in the protein
    $count{$_}++ for split '', $seq;

    for my $a (@aa) {
        $count{$a} ||= 0;
        printf "%s:%s/%s=%.0f%%\n", $a, $count{$a}, length($seq), 100 * $count{$a} / length($seq);
    }

    print "\n";
}