use strict; use warnings; use Data::Dumper; my $path ='c:/test'; my %files_per_user; #HOA foreach my $file (glob("$path/*")) { next unless -f $file; # skip directories # if any exist my ($user,$detail_name) = split ('-',$file,2); push @{$files_per_user{$user}},$detail_name; } print Dumper \%files_per_user; foreach my $user (sort keys %files_per_user) { print "",(split("/",$user))[-1],"\n"; print " $_\n" for @{$files_per_user{$user}}; } __END__ What the TEST Directory looks like: Directory of C:\test 02/26/2020 09:52 PM . 02/26/2020 09:52 PM .. 02/26/2020 09:22 PM 0 maur-1110.tiff 02/26/2020 09:21 PM 0 maur-1111.psd 08/05/2019 01:14 AM subdirtest 02/26/2020 09:20 PM 0 TUMI-1354839054_alt1_.psd 3 File(s) 0 bytes $VAR1 = { 'c:/test/TUMI' => [ '1354839054_alt1_.psd' ], 'c:/test/maur' => [ '1110.tiff', '1111.psd' ] }; TUMI 1354839054_alt1_.psd maur 1110.tiff 1111.psd