#!/usr/bin/perl -w use strict; use Data::Dumper; my %hash = ( x => 'line 1', z => [ 1, 16, 4, 2 ], y => { file=> 'test.txt', length=> 200, type => 'ASCII' }, c => [ 'j', 'a', 'p', 'h' ], b => [ {x => 1, a => 2, z => 3}, {1 => 'x', 2 => 'a', 3 => 'z'}, ], a => [ [0,1],[1,1],[-1,1],[-1,-1] ] ); my $dump = Dumper(\%hash); print "Sorted:\n", sort_dumper($dump,'auto',1); print "\nRaw:\n", $dump; # this sub will return sorted standard Data::Dumper output. # an alphabetic sort is the default setting, example: # sort_dumper( Dumper(\%hash) ); # numeric sort if called with a true second argument, example: # sort_dumper( Dumper(\%hash), 1 ); # an automatic sort choice based on first char in first element # is done if the second param is specified as 'auto', example: # sort_dumper( Dumper(\%hash), 'auto' ); # arrays will be sorted if you pass a true third param # example (alpha sort, including sorting array elements): # sort_dumper( Dumper(\%hash), 0, 1 ); # to sort everything automatically you call it: # sort_dumper( Dumper(\%hash), 'auto', 1 ); sub sort_dumper { my ($dump, $numeric, $array) = @_; my %pairs = $array ? ('['=>']', '{'=>'}') : ('{'=>'}'); # get opening details my ($start, $open, $indent) = $dump =~ m/^(.+(.)\n)(\s*)\S/; return $dump unless $open and exists $pairs{$open}; # get closing details my ($close) = $dump =~ m/^(\s*$pairs{$open}.?\n)\z/m; # get the key value assignments into an array $dump =~ s/^\Q$start\E|\Q$close\E\z//g; my @array; push @array, $1 while $dump =~ m/^($indent(\S).*?)(?=^$indent(?:\2|\d)|\z)/msg; $_ = sort_dumper($_,$numeric,$array) for @array; # add trailing comma to last element $array[-1] =~ s/\n$/,\n/; # sort our key value chunks, numeric or alpha depending # choose automatically if specified and use the Schzartzian # transform for efficiency on numeric sort to get digits $numeric = $array[0] =~ m/^\s*'?\d/ if $numeric eq 'auto'; @array = $numeric ? map{$_->[0]}sort{$a->[1]<=>$b->[1]}map{[$_,num($_)]}@array : sort @array; sub num { $_[0] =~ m/(-?\d+)/; $1 || 0 } # remove trailing comma from (new) last element $array[-1] =~ s/,\n$/\n/; return join'', $start, @array, $close; } __END__ Sorted: $VAR1 = { 'a' => [ [ -1, -1 ], [ -1, 1 ], [ 0, 1 ], [ 1, 1 ] ], 'b' => [ { '1' => 'x', '2' => 'a', '3' => 'z' }, { 'a' => 2, 'x' => 1, 'z' => 3 } ], 'c' => [ 'a', 'h', 'j', 'p' ], 'x' => 'line 1', 'y' => { 'file' => 'test.txt', 'length' => 200, 'type' => 'ASCII' }, 'z' => [ 1, 2, 4, 16 ] }; Raw: $VAR1 = { 'x' => 'line 1', 'a' => [ [ 0, 1 ], [ 1, 1 ], [ -1, 1 ], [ -1, -1 ] ], 'y' => { 'length' => 200, 'file' => 'test.txt', 'type' => 'ASCII' }, 'b' => [ { 'x' => 1, 'a' => 2, 'z' => 3 }, { '1' => 'x', '2' => 'a', '3' => 'z' } ], 'z' => [ 1, 16, 4, 2 ], 'c' => [ 'j', 'a', 'p', 'h' ] };