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

Converting all occurrences of \ to \\ in $dirname in &moveextrafiles oddity I'm trying to pass a directory name (entered from CLI) & create that directory on HD. The directory name is passed as a parameter to &moveextrafiles. This is the program output in AP522 Win32:

Couldn't make directory c\\:\\xtrafiles c\\:\\xtrafiles
and here is the code snippet

use strict; my @extrafiles = ("blah.txt","wah.txt"); &moveextrafiles(quotemeta("c:\extrafiles"),@extrafiles); exit; sub moveextrafiles { my ($dirname,@filestomove) = @_; # change \ to \\ e.g. c:\extrafiles to c:\\extrafiles $dirname =~ s#\\#\\\\#g; print "$dirname\n"; mkdir $dirname,0777 or die "Couldn't make directory $dirname\n"; # Dir created. Now move files. # print join("\n",@filestomove); }
any advice about where that illegal char is coming from & how to replace / with //'s?

TIA!

dmtelf

Replies are listed 'Best First'.
(jcwren) Re: Converting all occurrences of \ to \\ oddity
by jcwren (Prior) on Sep 12, 2000 at 19:21 UTC
    You either need to use single quotes for the line that defines 'c:\extrafiles', or use "c:\\extrafiles"

    quotemeta does what you think it does, but not until *after* the quoted string has been evaluated.

    I also don't think you're going to want to quotemeta those directory names. Windows will not be very happy getting a drive reference like 'c\:\\somedir'. Windows wants to see only a real path.

    For the record, Windows doesn't care about the direction of the slashes in internal functions. The only thing that cares are the user interface programs. DOS/Windows has supported '/' as a path separator since 5.0 or so, as I recall. So, you should be able to save your self a lot of trouble with this, as long as you aren't invoking the shell to process any of your arguments.

    --Chris

    e-mail jcwren
RE: Converting all occurrences of \ to \\ oddity
by OzzyOsbourne (Chaplain) on Sep 12, 2000 at 20:20 UTC

    I was doing something like this on win32 (win2k), and I found that if you simply use forward slashes in single quotes, the code becomes easier to read, and DOS still understands it.Such as:

    $dirname='c:/dir/textfile.txt'

    I eventually wanted to convert the slashes to backslashes for logging (so that I could copy log output directly to a command prompt). I inserted this little bit into the end:
    ('/' to '\')

    foreach (@files){ s/\//\\/g; }
    conversely '\' to '/':
    foreach (@files){ s/\\/\//g; }
    and your answer('\' to '\\'):
    foreach (@files){ s/\\/\\\\/g; }

    I would still simply avoid this and use the forward slash if you can...

    -ozzyosbourne

      This is true on some Win32 platforms, but not Win2k. Win2k uses a forward slash to start a flag, and does not look for a space before that slash, causing a problem with using forward slashes in your paths. On the other hand it works great for NT4. Just beware if (when) you change to Win2k.

        Actually, it is a problem under Win NT as well. But it is only a problem if you pass the file name on the command line to a program that will interpret the / as you have described. Many, many Win NT programs don't have this problem and even cmd.exe supports using / as a directory separator (but cmd.exe's built-in commands don't). But many (most?) programs from Micrsoft interpret / as a command-line option. If you don't pass the filename to an external command, then the / should always work.

        Based on your wording, it sounds like the problem under Windows 2000 is similar. I haven't played with W2K, so I'd appreciate some clarification.

        Note that there are at least two places in the Win32 API where / can't be used in place of \: Registry calls and DefineDosDevice().

        Update: ...and for the first case, that is why we have Win32::TieRegistry::Delimiter("/").

                - tye (but my friends call me "Tye")
Re: Converting all occurrences of \ to \\ oddity
by Carl-Joseph (Scribe) on Sep 13, 2000 at 22:35 UTC

    If the path is entered from the command line, you need not tamper with the backslashes. (See the code below.)

    Also, I notice that cmd.exe on Win2K treats:

    c:\mydir
    and
    c:\\mydir

    as equivalent. For example, the following works fine:

    md c:\\mydir\yourdir pushd c:\mydir\\yourdir popd

    Here is some code that takes a path from the user and creates the specified directory:

    print "Enter string: "; $dirname = <STDIN>; # # Must chop the string that the user entered, # since mkdir won't accept a directory name # that contains a newline character. # chop $dirname; # # This line is optional (at least on # Win2K), since cmd.exe considers # c:\mydir and c:\\mydir to be # equivalent. # # So double the slashes or not, # as you please. # $dirname =~ s{\\}{\\\\}g; print "Creating . . . $dirname\n"; mkdir($dirname, 0777) || die "Couldn't create $dirname. Error: $!\n";

    Carl-Joseph

      Just a note:

      You may consider using File::Path so the user can create a diretory structre.

      That would be cool :-)

      --
      Casey
         I am a superhero.