use strict; use warnings; use Data::Dumper; my %hash= ( Group1 => 'ATG1,ATG2,ATG4,ATRG7', Group2 => 'ATG1,ATG9', Group3 => 'FYCO1,LSM2', Group4 => 'ATG1,MAM2', Group5 => 'LSM2', ); my (%newhash,$i,%combinegroups,%splittedhash); foreach my $key (keys %hash){ my @values ; if($hash{$key} =~ /,/){ @values = split(/,/,$hash{$key}) ; $splittedhash{$key} = [ @values ]; }else{ push(@values,$hash{$key}); $splittedhash{$key} = [ @values ]; } if(++$i == 1) { my @newvalues; push (@newvalues,$key) for(0..scalar @values); @newhash{@values} = @newvalues; }else{ foreach (@values){ if(exists $newhash{$_}){ $combinegroups{$newhash{$_}.":".$key}++; }else{ $newhash{$_} = $key; } } } } foreach my $key (keys %combinegroups){ my ($firstgroup,$secondgroup) = split(/:/,$key); my %unique; @unique{@{$splittedhash{$firstgroup}},@{$splittedhash{$secondgroup}}} = (); $hash{$firstgroup} = join(',',keys %unique); @{$splittedhash{$firstgroup}} = keys %unique; delete $hash{$secondgroup}; } print "FINAL HASH\n",Dumper \%hash;