2013-05-06 51 views
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); close(ALL_OUTPUTS_GENERATED);

+1

您预计会有多少个$ Tile_Number值?对于每个值,$ Line有多少个值?我认为你寻求的答案取决于这些数字。另外,为什么您要节省内存,因为许多现代计算机都有可用的RAM? – AdrianHHH 2013-05-06 16:41:50

+0

我期待96 $ Tile_Number,每个包含10-15百万个条目,并且为8个项目并行执行此操作。 – 2013-05-06 17:15:53

回答

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

谢谢,鲍罗廷!我不需要按照他们阅读的方式排序。。 我曾想过使用每个$ Tile_Number数组的,但我不知道如何打印每个$我的阵列:( 我会贴在我的问题我的代码在 – 2013-05-06 17:16:46

+0

@CarmenSandoval:我 – Borodin 2013-05-06 18:17:25

+0

哇,鲍罗丁,这太好多了,非常感谢,希望这对未来的其他人有用,当他们需要做类似的事情时: I只有一个关于你的代码的问题 - 这部分是如何工作的:? 'while(my($ tile,$ fh)= each%filehandles){ close $ fh' – 2013-05-06 18:40:26

相关问题