I tried to keep it similar to your original logic:
use strict;
use warnings;
use Data::Dumper;
my @filenames = <DATA>;
chomp @filenames;
my %files;
foreach my $file (@filenames) {
my $last = \%files;
my @parts = split(/[-_.]/,$file);
for my $i (0 .. $#parts) {
$last->{$parts[$i]} = (($i != $#parts) ? {} : 1) if (!exists($
+last->{$parts[$i]}));
$last = $last->{$parts[$i]};
}
}
print Dumper(\%files);
my $test;
$test->{'0001'}{test}{thing}{sgi} = 1;
$test->{'1'}{tif} = 1;
$test->{'2'}{tif} = 1;
$test->{'10'}{tif} = 1;
$test->{final}{'0001'}{tif} = 1;
$test->{final}{'0002'}{tif} = 1;
$test->{final}{'0003'}{tif} = 1;
$test->{final}{'0004'}{tif} = 1;
print Dumper($test);
__DATA__
0001-test-thing.sgi
1.tif
10.tif
2.tif
final-0002.tif
final-0003.tif
final-0004.tif
final-0001.tif