#!/usr/bin/perl use strict; use warnings; use Data::Dumper; my %data; my %hits; my %used; while() { next unless /^\s*\[([^\[\]]+)\]:\s*(.+?)\s*$/s; my $name=$1; my @param=split(/\s*,\s*/,$2); for(@param) { if(/\[([^\[\]]+)\]/) { push(@{$data{$name}},{type => 'node', value => '', name => $1}); push(@{$hits{$name}},$1); $used{$1}++; } else { push(@{$data{$name}},{type => 'value', value => $_, name => ''}); } } } print Dumper(\%hits); printout(\%data); my $do=1; while($do) { $do=0; for my $k (sort keys(%hits)) { my $v=$hits{$k}; my $prnt=0; for my $p (reverse 0..$#$v) { next if(exists($hits{$v->[$p]})); next if($used{$v->[$p]} > 1); my $kk=splice(@$v,$p,1); my $del=delete($data{$kk}); delete($hits{$k}) unless(@$v); for my $pp (reverse 0..$#{$data{$k}}) { if($data{$k}->[$pp]->{name} eq $kk) { splice(@{$data{$k}},$pp,1,@$del); } } $do++; $prnt++; } if($prnt) { print "---------------------\n"; printout(\%data); } } } print "---------------------\n"; printout(\%data); sub printout { my ($data)=@_; for my $key (sort keys(%$data)) { my @vals; for(@{$data->{$key}}) { if($_->{type} eq 'node') { push(@vals,"[$_->{name}]"); } else { push(@vals,$_->{value}) } } print "[$key]:".join(", ",@vals)."\n"; } } __DATA__ [1]: a, b [2]: c, [1] [3]: d, e [4]: f, [3] [5]: g, h [6]: i, [5] [7]: [2], [4] [8]: j, [6] [9]: [7], [8]