2013-05-06 39 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

相關問題