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

I am trying to use unlink to delete files from a directory where are the file names are numerical. My problem is that I need to get rid of ones that are >=00000000000010001A001 and <=00000000000010174A001 - this is what I have so far - I assume there is a problem with the pattern matching ( I have not made it to the unlink part cause I cannot even get this to match)
#!/usr/bin/perl -w opendir(MDSDIR,"/mds/nvision1"); while ( $file = readdir(MDSDIR) ) { if ($file =~/0000*\./) { print $file; $temp = chop($'); print "$temp\n"; } } closedir(MDSDIR);
any help would really be appreciated - cheers

Edit: chipmunk 2001-03-31

Replies are listed 'Best First'.
Re: Pattern Matching
by chromatic (Archbishop) on Mar 29, 2001 at 01:57 UTC
    You ought to check to see if your opendir call succeeds. Here's my take on the regex:
    if ($file =~ /^0{12}(\d{5})A001$/) { next unless ($1 > 1 and $1 < 10174); # unlink $file goes here }
Re: Pattern Matching
by JSchmitz (Canon) on Mar 29, 2001 at 03:05 UTC
    Thanks for all the imput - My friend here at work helped me out and we ended up going interactive which seemed easier
    Here is the working script
    #!/usr/bin/perl -w print "Enter starting file name: "; $start = <>; print "Ending file name: "; $end = <>; chomp($start); chomp($end); opendir(MDSDIR,"/mds/nvision1"); while ( $file = readdir(MDSDIR) ) { if ($file =~ /000[0-9A-C]*\./) { $temp = $&; chop($temp); if ( $temp ge $start && $temp le $end ){ $temp = "/mds/nvision1/" . $temp . ".$'"; print "unlinking $temp\n"; # unlink($temp); } } } closedir(MDSDIR);
Re: Pattern Matching
by kal (Hermit) on Mar 29, 2001 at 00:49 UTC

    Firstly, tell us what you are trying to do! By chopping $', you appear to want to match the "number" section of the file name (i.e., without the preceding 0s). Is this correct? If so, no need - 00001 == 1, you don't need to do a "if ('00001' =~ /0*/)" and use "$' == 1", if you see what I mean!!

    Next, try not to use $' unless you have to. Bad practice, when a regex match does just as well. I would suggest something similar to:

    $file =~ /^0000(?:0*)(.*)$/; $temp = $1;

    .. to achieve your goal. I assume, from your regex, that you only want files with more than three preceding zeros. Mine does that, throws away any other preceding zeros, and passes the rest to $temp. Obviously, if it doesn't match then $temp is undef - don't unlink it :)

    Now, you can do the comparison by treating the string as a hex number and then testing it. But, I notice A001 is on the end of both - is this common to all files? If so, you could change the regex above to /^0000(?:0*)(.*)A001$/, and then just treat $temp as a number, no fiddling.

    Also, if you at all can, change the (.*) to something more strict - if you know that the file will have a five-digit number, for example, express that in the regex. And comment what the regex is _supposed_ to match!!

Re: Pattern Matching
by how do i know if the string is regular expression (Initiate) on Mar 29, 2001 at 00:21 UTC
    There is a problem with your regex as a matter of fact.

    Try:

    if($file =~ /0000.*\/)

    The '.' matches any character and the '*' quantifies the '.' to match 0 or more times.

    - Frank

Re: Pattern Matching
by Sifmole (Chaplain) on Mar 29, 2001 at 00:23 UTC
    I see a couple of issues.. First, I would anchor the pattern to the front of the string by using a '^'. Secondly, the '\.' states that you are looking for an actual '.' rather than the set represented by a '.' in regexs. I would do something like: /^0{4,}./ The $' will now hold everything beyond the first non-zero character (specifically not including the first non-zero character). Also, I get an error when I try to "chop" $'. Hope this helps.