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

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.