我做了哈希哈希,其中文件的所有行都被分类为“主”哈希的键,具体取决于它们的第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);
答案 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: $!};
}