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

Hi All,
We have been moving from an older version of Perl to 5.6 (ActiveState build 628) and came against a problem with glob. We have strangely named files (containing numbers signs) and glob seems to behave differently:
sub Test { my $fname = "D:\\development\\project\\dev\\-71.95*_41.0528*."; my @list = glob($fname); print "I found [$#list] entries\n"; }
Under Perl version 5.005 (build 508) this returns 2 files (as it should). Under the new version, it doesn't return anything.

We also tried File::DosGlob::glob and it didn't return anything, though dir did give results.
How can we get the old glob functionality in the new version? ActiveState's site has been down for two days now (at least as far as I can tell) and we have nowhere to turn, please, help us !!! ;-)

perchance
--- The Lifting

Replies are listed 'Best First'.
Re: Glob on Win32: porting 5.005 to 5.6
by tachyon (Chancellor) on Sep 03, 2001 at 22:26 UTC

    After a bit of experimentation it is the final . character at the end of your filename that is causing the problems. This . is lost by Windows even if you make files by that name with a trailing period char. I had to write my own _glob sub to prove that - it did not work either although it should have. Looking at the filenames from readdir demonstrated the problem. The lost . is the key. You do not really need it anyway as it will match with the * if it was there which it is not.

    open F, ">C:/development/project/dev/-71.95_41.0528." or dir $!;close +F; open F, ">C:/development/project/dev/-71.95AAA_41.0528AAA." or dir $!; +close F; open F, ">C:/development/project/dev/-71.95BBB_41.0528BBB." or dir $!; +close F; open F, ">C:/development/project/dev/-71.95CCC_41.0528CCC." or dir $!; +close F; my $fname = "C:/development/project/dev/-71.95*_41.0528*."; my @list = glob($fname); print "I found " . scalar @list . " entries\n"; print "$_\n" for @list; # lose the . at the end - Windows does! my $fname = "C:/development/project/dev/-71.95*_41.0528*"; my @list = glob($fname); print "I found " . scalar @list . " entries\n"; print "$_\n" for @list; # this is how to roll your own glob but you don't need to!!! sub _glob { my($dir,$file) = shift =~ m!^(.*?)([^\\/]+)$!; opendir DIR, $dir or die $!; $file = quotemeta $file; $file =~ s/\\\*/.*/g; $file = qr/$file/; my @files = grep{/$file/}readdir DIR; closedir DIR; $_ = $dir.$_ for @files; return @files; } # here is the output, note the CHANGE to the filenames!!! # You can see we named the "file." but they end up being # called "file" That's Windows for you __END__ I found 0 entries I found 4 entries C:/development/project/dev/-71.95AAA_41.0528AAA C:/development/project/dev/-71.95BBB_41.0528BBB C:/development/project/dev/-71.95_41.0528 C:/development/project/dev/-71.95CCC_41.0528CCC

    PS forward slashes / work fine as shown. Perl converts to Windows \ as required. Saves all the \\ stuff.

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

      I'm sorry about the dot at the end, it was one of the many variations on a theme we were trying out - it didn't have to be there, and so, wasn't the actual reason.
      However, your code helped me understand two things that were causing problems:
      • The \\ were not working properly. (I am not completely sure why, though).
      • There may have been conceptual problems with globbing on a relative path (probably in conjunction with the previous item), opening the directory implicitly.
      We replaced the \\s with /s and all is well.
      You have brought us great joy and peace,
      Thank you thank you thank you!

      perchance
      --- Me in Honey

        Glad you got it sorted. Perl's automagical conversion of / to \ for Win 32 is great. If you want to get Win32 type names for display to users you just do something like this:

        my $perl = '/foo/bar/baz'; (my $win = $perl) =~ tr!/!\\!; print "Perl still sees: $perl\n"; print "But we can print: $win\n";

        cheers

        tachyon

        s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print