G'day Zsolt,
Your code uses a lot of older coding styles which I recommend you aim to move away from. These include: leading '&' on subroutine calls; use of package rather than lexical variables; and a lack of strict and warnings pragmata.
There are a number of ways to achieve what you want. In the code below, I've continued your use of opendir. The core File::Find module is popular, as are a number of related CPAN modules — I expect other monks may provide you with examples of those.
I've used fairly generic options for inclusions and exclusions — adapt to your needs.
I created this directory structure for testing (in the spoiler):
Here's the code:
#!/usr/bin/env perl use strict; use warnings; use autodie; use File::Spec; use List::Util 'shuffle'; # For production, you'd probably want to read the # following values from options, config, etc. my $dir = '/home/ken/tmp/pm_11150231_dir_rand_select'; my @includes = (qr{\.x$}, qr{\.z$}); my @excludes = (qr{skip$}, qr{inc2\/p\.z$}); my $list_length = 3; my $re = { inc => qr{(?:@{[join '|', @includes]})}, exc => qr{(?:@{[join '|', @excludes]})}, }; my @all_files; get_files(\@all_files, $dir, $re); my @playlist = (shuffle @all_files)[0 .. $list_length - 1]; print "$_\n" for sort @playlist; sub get_files { my ($collected, $dir, $re) = @_; return if $dir =~ $re->{exc}; opendir(my $dh, $dir); for my $file (grep ! /^(?:\.|\.\.)$/, readdir $dh) { my $path = File::Spec::->catfile($dir, $file); next if $path =~ $re->{exc}; if (-d $path) { get_files($collected, $path, $re); } elsif (-f _) { next unless $path =~ $re->{inc}; push @$collected, $path; } else { # maybe handle other file types here } } return; }
Here's a couple of sample runs:
$ ./rand_select_files.pl /home/ken/tmp/pm_11150231_dir_rand_select/inc1/h.x /home/ken/tmp/pm_11150231_dir_rand_select/inc1/j.z /home/ken/tmp/pm_11150231_dir_rand_select/inc2/n.x
$ ./rand_select_files.pl /home/ken/tmp/pm_11150231_dir_rand_select/a.x /home/ken/tmp/pm_11150231_dir_rand_select/c.z /home/ken/tmp/pm_11150231_dir_rand_select/inc1/j.z
— Ken
In reply to Re: Add a fixed number of unique elements to hash
by kcott
in thread Add a fixed number of unique elements to hash
by Vasek
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |