suekawar has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks,

I need to get some files under a spicific dir

DIR = local;

the files under DIR are tim1 , tim2, tim3 .... tim50

I want to only get the files from tim15 to tim50 and applay some command in each one , so put them inside an array

I am trying somthing like

foreach $vob (@vobs) { # get all files under each vob my @names = grep -f, <c:/testFolder/local/*tim>; }

Replies are listed 'Best First'.
Re: getting files from Dir
by Zaxo (Archbishop) on Jan 24, 2003 at 05:40 UTC

    You can build a list of names you want like this:

    my $dir = 'c://testFolder/local/'; my $base = 'tim'; my @names = grep {-f} map {$dir . $base . $_} 15..50;

    After Compline,
    Zaxo

Re: getting files from Dir
by jepri (Parson) on Jan 24, 2003 at 05:32 UTC
    I use a different approach:

    opendir DH, "/directory"; @files = readdir DH; closedir DH; foreach (@files) { /tim(\d*)/; $num = $1; if ( ($num > 14 ) && ( $num < 51) {push @wanted, $_}; }

    Code is untested, take your chances. ObBrag: I can make it smaller, but that's harder to read.

    Update: Changes made as suggested by davis - thanks. Personally I think open and opendir should be unified, but I guess there's some good reason why not.

    ____________________
    Jeremy
    I didn't believe in evil until I dated it.

      open DH, "/directory";
      @files = readdir DH;
      close DH;
      I'd imagine you want to change the "open" and "close" to "opendir" and "closedir" respectively
      cheers
      davis
      Is this going out live?
      No, Homer, very few cartoons are broadcast live - it's a terrible strain on the animator's wrist
      Why don't you check your match for success? If if fails, you get the $1 from the previous iteration. That's probably not what you intended. Also, I'd use \d+ instead of \d* since we're not interested in matching tim without any following digits. It probably should be anchored to the front of the string too, by the OP's spec.
      my @wanted; opendir my $dh, $dir or die "Failed opening $dir: $!"; foreach (readdir $dh) { next unless /^tim(\d+)/; my $num = $1; push @wanted, $_ if $num > 14 and $num < 51; } closedir $dh;
      Personally, I'd wrap the whole thing in a do block and use grep, so that I don't need to track my handles explicitly:
      my @tim_file = do { opendir my $dh, $dir or die "Failed opening $dir: $!"; grep { my ($num) = /^tim(\d+)/; defined $num and $num > 14 and $num < 51; } readdir $dh; };
      Note that when you assign a match's captures to a list, failed expressions will return undef, so here I can implicitly test for success by testing the definedness of $num.

      Makeshifts last the longest.

Re: getting files from Dir
by jdporter (Paladin) on Jan 24, 2003 at 14:29 UTC
    Well, you said you want to get all the files under each vob, and the name of the vob is in $vob . . . but you don't use that variable anywhere.
    I wonder if perhaps you meant
    my @names = grep -f, <$vob/*tim>;
    or
    my @names = grep -f, <c:/testFolder/$vob/*tim>;
    or something like that.

    jdporter
    The 6th Rule of Perl Club is -- There is no Rule #6.

Re: getting files from Dir
by vek (Prior) on Jan 24, 2003 at 13:47 UTC
    You've had some good suggestions so far. The only other thing I'd add is that if you go the opendir route, it's always a good idea to check the return value (returns 1 on success, 0 on failure):
    opendir(DIR, $somedir) || die "Could not open $somedir - $!\n";
    -- vek --

      As an aside to this, if you are using ||, make sure you've got the parentheses around the arguments passed to opendir. Otherwise you'll be testing for the value of $somedir and dying if $somedir is an empty or undefined scalar. Better yet, just use 'or', so that your test on the success of opening the directory will do what you are expected, whether or not the parentheses are present:

      opendir DIR, $somedir or die "Could not open '$somedir': $!";

      Also, if your script is going to be extremely long, you might want to exclude the newline (\n) at the end of your die statement, to make debugging easier (ie: knowing which line in your program died on you. In this case however, it seems to be a short script, so you'll probably know where the problem is. :)


      "User error. Replace user and press any key to continue."

        You make a couple of good points Coruscate and are probably worth pointing out to avoid confusion. I made that observation myself in this thread. For the record though, I generally use parentheses around functions (just my coding style) and therefore use || and && when testing return values:
        open($someFile) || die "Couldn't open $someFile - $!\n"; opendir(DIR, $someDir) || die "Couldn't open $someDir - $!\n"; system($shellCommand) && die "Couldn't run $shellCommand - $!\n";
        -- vek --