6

I can only imagine I'm not searching correctly; this seems like an obvious question to be asked here. My apologies if this is a duplicate.

I'm writing a Perl program that will take a filename as a command-line argument. I need to convert the filename (or the filename with a relative path attached) to an absolute path (specifically to work with Win32::OLE).

I tried using Cwd's 'abs_path', and that almost does what I want, but it returns it using a Unix-style path instead of a Win32 one.

Is there a module that will convert the path, or perhaps a better module to use in the first place?

romandas
  • 4,086
  • 7
  • 29
  • 33
  • 3
    What do you mean by Unix style paths? Can you show examples? Is it not using the drive letter? If it's just slashes, Windows doesn't care what direction they go. Are you passing this path to something that is complaining? – brian d foy Oct 06 '09 at 20:57
  • It uses the drive letter, but yes, I mean the forward slashes. I have learned since asking this question that Windows will accept the forward slashes (though I have not tried it yet using the Win32::OLE + Word VBA construct I'm building -- I'm home now). But.. regardless of whether you can get away with doing something.. doesn't it make sense to give the computer what it expects, as opposed to being ambiguous? And in Windows' case, I've only seen it provide backslashed paths. Does that make sense, if a bit pedantic? I'm asking truly.. I'm curious as to the answer. – romandas Oct 07 '09 at 02:09

4 Answers4

13

I use rel2abs from File::Spec. You have to be careful though: that might call getdcwd from Cwd, and it will assume that you want the current working directory for the current drive. If the file is on some other drive, you'll have to fix that up yourself or supply the second argument to set the base path.

brian d foy
  • 129,424
  • 31
  • 207
  • 592
  • +1 and accepted. I'm going to assume if the file is on another drive, that the user will give an absolute path to it. To be honest, I'm not sure how one could specify a file (via command-line) on a different drive but not use a drive letter... Do you have any experience with that happening? – romandas Oct 07 '09 at 02:11
  • 2
    Non-NT Windows is funny. "D:foo.txt" is foo.txt in the current directory on drive D. It's not the *root* of drive D because the path component doesn't start with a [back]slash. Each process maintains a current directory *for each drive*. It's a DOS legacy thing, and according to a Microsoft KB article no longer applies to NT-based windows. – hobbs Oct 07 '09 at 07:06
  • I ran into this problem with Archive::Extract on Windows 2003. My fix was to skip the guessing from getdwcd and supply the cwd myself. It's a resolved bug in that module, so you can check rt.cpan.org to see the patch. – brian d foy Oct 07 '09 at 09:23
4
use File::Spec::Functions qw(rel2abs);
print rel2abs($ARGV[0]), "\n";
FMc
  • 41,963
  • 13
  • 79
  • 132
-1
my($foo) = abs_path($some_file);
$foo =~ s{/}{\\}g;

print "FOO: $foo\n";
Joe Casadonte
  • 15,888
  • 11
  • 45
  • 57
-1

I use Cwd's abs_path and then use a regex to convert the slashes when I really need it done. But I've found that for most uses, Unix-style slashes work just fine. It's only for the occasional "pass a filename to that annoyingly limited program" that I end up needing to convert the slashes.

use Cwd 'abs_path';
my $path = abs_path($rel_path);

# and only if necessary...
$path =~ s'[/\\]+'\\'g;  # use Windows-style slashes
$path =~ s'^\\'\\\\';    # handle network path

But then.. I use a lot of network paths, with or without a mapped drive reference. Your mileage may vary.

Rini
  • 197
  • 2
  • 7