use strict; use warnings; use File::Copy; my $source_path = "/some/path"; my $sorted_path = "/some/other/path"; # get the set of existing sorted directories: my %sorted_dir; opendir( SORTED, $sorted_path ) or die "$sorted_path: $!\n"; while ( my $name = readdir( SORTED )) { if ( -d "$sorted_path/$name" and $name =~ /^(\d+_)/ ) { my $dir_key = $1; $sorted_dir{$dir_key} = $name; } } closedir SORTED; # go through the files to be sorted: opendir( SOURCE, $source_path ) or die "$source_path: $!\n"; while ( my $file = readdir( SOURCE )) { my $src = "$source_path/$file"; next unless ( -f $src and $file =~ /^(\d+_)/ ); my $target_key = $1; if ( not exists( $sorted_dir{$target_key} )) { warn "No directory exists in $sorted_path to hold $file\n"; next; } my $dest = "$sorted_path/$sorted_dir{$target_key}/$file"; if ( -f $dest ) { warn "$src already exists as $dest; not copied\n"; next; } copy( $src, $dest ) or warn "failed to copy $src to $dest: $!\n"; } closedir SOURCE;