Question: I have a 2.5GB file and want to store the contents into a hash.
The input file is somewhat like this:

Report.txt

```
chain_name    number    classification    description

chain_name    number    classification    description

chain_name    number    classification    description

chain_name    number    classification    description

```

and so on .......

This is the code I have written for this:

```
open (my $rept, "< report.txt");
open (o_f, "> output.txt");
my %hash;
while ( my $line1 = <$report_fh>)
{
  chomp $line1;
  (my $chain, my $number, my $classification , my $description) = split / {2,}/, $line1;
  #print o_f ("$chain-------->$description\n");  # for checking whether splitting took place successfully, this works perfectly.
  $hash{$chain} = $description;
}   

# for printing the hash values 
while ( my ($k,$v) = each %hash ) 
{
  print o_f (" $k ===> $v\n");
}

```

The hash printed is all jumbled up (not in the same order as how it is in the input file) and not all the lines are being printed while I am trying to print the hash. 

I have been banging my head figuring this out for hours, need help with this.

Answer: 
hashes are *explicitly* unordered. Their output order is random-ish. That's by design - any time you're relying on hash ordering, then you're doing something nasty. It did get a bit worse recently (e.g. more obvious that your code was wrong). [Algorithmic Complexity attacks](http://perldoc.perl.org/perlsec.html#Algorithmic-Complexity-Attacks) so the effect is more noticeable as of Perl 5.18. But this hasn't changed the underlying problem that hashes aren't ordered, and shouldn't be assumed to be. 

If you need *ordered* data, this is why we have arrays. You can either: 

* push your key into an array to maintain 'file order'.
* use `sort` to order the keys for output.

So in your code, you might do: 

```
$hash{$chain} = $description;
push ( @order, $chain ); 

```

And then to print:

```
foreach my $key ( @order ) { 
   print "$key => $hash{$key}\n";
}

```

Or alternatively:

```
foreach my $key ( sort keys %hash ) { 
    print "$key => $hash{$key}\n"; 
}

```

It may also be worth looking at [`slices`](http://perldoc.perl.org/perldata.html#Slices) of hashes - which let you extract a specific sequence of values.

NB: `%hash` is a nasty name for a variable. Call it something descriptive. Trust me on this, there's nothing worse than trying to debug code where variables are like that. I would suggest: 

```
my %description_of;

```

So then you can write:

```
$description_of{$chain} = $description;

```
No need to store anything in memory here. Go straight from the old file to the new one.

```
open(my $old, '<', 'report.txt') or die $!;
open(my $new, '>', 'output.txt') or die $!;

while (<$old>) {
    chomp;
    my @parts = split(/\s+/);
    print $new "$parts[0] ===> $parts[3]\n";
}

close($old);
close($new);

```