在新文件中打印每个哈希键及其值?

时间:2013-05-06 15:08:03

标签: perl hash printing file-handling

我做了哈希哈希,其中文件的所有行都被分类为“主”哈希的键,具体取决于它们的第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为“master”哈希中的每个键打开一个新文件并打印其所有键?

代码:

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);

1 个答案:

答案 0 :(得分:2)

我认为你应该有一个数组哈希,而不是哈希的哈希。但是,您可以使用此

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

请注意,这些行不会与读取的顺序相同。你必须使用一个数组。

我不清楚您的打印概念,因为每行都会添加并保存内存。你的意思是你想要打印每一行而不是将其添加到哈希?也许您应该向我们展示您的完整代码。


<强>更新

这是您可能喜欢的替代方案。它并不存储文件中的数据。相反,它会在读取时从每一行中提取磁贴编号,并写入与该编号对应的文件。

有一个文件句柄的散列,其中将tile数作为键,每次读取一行时,都会检查散列以查看是否已存在该tile数的文件句柄。如果没有,则在写入该行之前打开一个新的。

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: $!};
}