0

ハッシュのハッシュを作成しました。ファイルのすべての行は、5 番目のフィールドの値に応じて「マスター」ハッシュのキーにソートされます。

%Tilesには n 個のキーがあり、各キーは異なる$Tile_Number.

の各要素の値は、現在のハッシュ キーの番号である%Tilesすべての行を含むハッシュ ハッシュへの参照です。$Tile_Numberこれらの新しいキー (行) の値はそれぞれ 1 です。

$Tiles{$Tile_Number}{$Line}=1$Tiles{$Tile_Number}多くの$Line=1エントリがあります。

$Tiles{$Tile_Number}ハッシュを個別のファイルに出力し、できればキーの作成時にファイルを作成し、$Tile_Number新しい$Tiles{$Tile_Number}{$Line}=1ものが追加されるたびに出力して、メモリを節約したいと考えています。

最終値 (1) を出力しないのが最善ですが、これは省略できると思います。

「マスター」ハッシュの各キーに対して新しいファイルを開き、そのすべてのキーを出力するように Perl に指示するにはどうすればよいですか?

コード:

use strict;
use warnings;


my ($Line) = "";
my (@Alignment_Line) = ();
my (%Tiles) = ();

my $Huge_BAM_File= $ARGV[0] or die $USAGE;

open(HUGE_BAM_FILE,"< $Huge_BAM_File") || die "Sorry I couldn't open the INPUT file:   $Huge_BAM_File !\n";

while(<HUGE_BAM_FILE>){

    ### Remove new line characters "\n"
    ### Split each line by "\t" and by ":" (for fields within READ ID FIELD)
    chomp;
    $Line = $_;
    @Alignment_Line = split(/\t+|\:/, $Line);

    my $Tile_Number = $Alignment_Line[4]


    ##########################################################
    ### Fill in hash of hashes %Tiles                      ###
    ### Key = $Tile_Number                                 ###
    ### Second key is $Line                    ###
    ### and is filled with a 1                     ###  
    ### Each key contains all the alignments with that tile### 
    ### number                                     ###
    ##########################################################

     $Tiles{$Tile_Number}{$Line} = 1;
     ##Here, I would like to write this new entry into the corresponding file, 
     and maybe remove it from the hash so the program doesn't run out of memory.
}

閉じる (HUGE_BAM_FILE); 閉じる (ALL_OUTPUTS_GENERATED);

4

1 に答える 1

2

ハッシュのハッシュではなく、配列のハッシュが必要だと思います。ただし、これを使用してハッシュを印刷できるようです

while (my ($tile, $lines) = each %Tiles) {
    open my $fh, '>', "$tile.txt" or die $!;
    print $fh $_ for keys %$lines;
}

行は、読み取られた順序とは異なることに注意してください。そのためには配列を使用する必要があります。

各行が追加されてメモリが節約されるため、印刷するというあなたの考えについては明確ではありません。ハッシュに追加する代わりに、各行を印刷したいということですか? おそらく、完全なコードを見せてください。


アップデート

ここにあなたが好きかもしれない代替案があります. ファイルからのデータはまったく保存されませ。代わりに、読み取り時に各行からタイル番号を抽出し、その番号に対応するファイルに書き込みます。

タイル番号をキーとするファイルハンドルのハッシュがあり、行が読み取られるたびに、そのタイル番号のファイルハンドルが既に存在するかどうかを確認するためにハッシュがチェックされます。そうでない場合は、行を書き込む前に新しい行が開かれます。

use strict;
use warnings;

my $USAGE;

my $bam_file = $ARGV[0] or die $USAGE;

open my $bam, '<', $bam_file"
    or die qq{Unable to open "$bam_file" for input: $!};

my %filehandles;

while (<$bam>) {
    chomp ($line = $_);
    my @fields = split /[\t:]/, $line;
    my $tile = $fields[4];
    unless ($filehandles{$tile}) {
      my $file = "$tile.txt";
      open $filehandles{$tile}, '>', $file
          or die qq{Unable to open "$file" for output: $!};
    }
    print $filehandles{$tile} $_;
}

while (my ($tile, $fh) = each %filehandles) {
  close $fh
      or warn qq{Unable to close file for tile number $tile: $!};
}
于 2013-05-06T15:29:50.903 に答える