Re: Windows paths in glob



Dmitry wrote:
OK, so there's a well-known difficulty with handling Windows-style
paths in glob: it doesn't like backslashes, nor does it like spaces.
One solution to that is to use Unix-style paths:

glob('C:\Documents and Settings\*'); # Doesn't work
glob('C:/Documents\ and\ Settings/*'); # Works

Problem is, the rest of Perl's built-in file-handling functionality
behaves the other way around. For instance, with -d:

-d 'C:\Documents and Settings'; # Works
-d 'C:/Documents\ and\ Settings'; # Doesn't work

Question: is there any way to use the same path string with glob and
with the rest of Perl, without having to convert them back and forth?

I find, just as in geenral under Win32, putting double quotes around the
path gets around problems like this:

C:\>perl -e "my @d = glob('"""C:/Documents and Settings"""/*'); print
qq{\n}, join(qq{\n}, @d), qq{\n};"

C:/Documents and Settings/Administrator
C:/Documents and Settings/All Users
[...]

*** Note that """, when used in a double quoted string, under the
cmd.exe shell yields a literal ", so the glob statement is effectively:

glob('"C:/Documents and Settings"/*');

*** This is only because the command was run from the command line; in
an actual script you would of course use a normal double quote around
the path (just like in the linux examples below.)


And this works for tests like -d as well:

C:\>perl -e "print int (-d """C:/Documents and Settings""")"
1
C:\>perl -e "print int (-d """C:/123Documents and Settings""")"
0


And this form works under linux as well:

$ perl -e 'my @d = glob(q{"/mnt/samba/win_hd/Documents and
Settings"/*}); print qq{\n}, join(qq{\n}, @d), qq{\n};'

/mnt/samba/win_hd/Documents and Settings/Administrator
/mnt/samba/win_hd/Documents and Settings/All Users

$ perl -e 'print int (-d "/mnt/samba/win_hd/Documents and Settings")'
1
$ perl -e 'print int (-d "/mnt/samba/win_hd/123Documents and Settings")'
0

This was tested under ActivePerl 5.6.1 and 5.8.7, and under linux using
5.10.0, 5.8.8, and 5.6.1.


So if you want to do it in a way that works on most platforms (at the
very least windows and *nix),

1) Use a forward slash, not a back slash, as a path delimiter.
I.E., C:/path to/somewhere/file.ext, and

2) Surround the path with quotes.
I.E., "C:/path to/somewhere/a long filename.ext", or
"C:/path to/somewhere"/file.ext, or
"C:/Documents and Settings/"

and you should be fine.

Hope this helps.

--
szr


.



Relevant Pages

  • Re: String searching in a FILE*
    ... Any career shell scripter who is worth the spare change they throw in his tin ... The * glob will probably miss files whose names begin with a dot. ... On Linux, which typically has GNU find, you could do okay if you used popen to ... POSIX.2 glob function which provides the same pattern matching. ...
    (comp.lang.c)
  • Re: recursive grep and openoffice
    ... I think it might depend on your glob ... Another poster mentioned enclosing the braces in quotes, "", to ... shell expansion. ... To UNSUBSCRIBE, email to debian-user-REQUEST@xxxxxxxxxxxxxxxx ...
    (Debian-User)
  • glob with accents
    ... We encouter a strange behaviour of "glob" when dealing with acents. ... On linux box 1: ... When issuing a glob command to retrieve a directory called ...
    (comp.lang.tcl)
  • Re: help with Globbing : use of -r with glob catches only half of the matching files ...
    ... globbing to check existense of a certain number of files on a linux ... In list context, ... because legal glob returns would ... "undef" is returned only once. ...
    (comp.lang.perl.misc)
  • Re: Windows paths in glob
    ... If you put double quotes aroudn the path *in* the string for glob, ... foreach('C:/Documents and Settings', 'C:\\Documents and Settings') { ...
    (comp.lang.perl.misc)