18

In case of Java, we can get the path separator using

System.getProperty("path.separator");

Is there a similar way in Perl? All I want to do is to find a dir, immediate sub directory. Say I am being given two arguments $a and $b; I am splitting the first one based on the path separator and joining it again except the last fragment and comparing with the second argument.

The problem is my code has to be generic and for that I need to know whats the system dependent path separator is?

DVK
  • 126,886
  • 32
  • 213
  • 327
Ram
  • 3,034
  • 11
  • 38
  • 46
  • 1
    Have you seen other questions? http://stackoverflow.com/questions/2859015/why-dont-my-perl-regexes-correctly-extract-a-filename-from-a-path , http://stackoverflow.com/questions/1818093/how-can-i-construct-os-independent-file-paths-in-perl – Zaid May 24 '10 at 13:36
  • 6
    For the benefit of search engines: this question and answers actually deal with the directory separator (usually slash or backslash). The path separator is a different thing (usually colon or semicolon) with a different purpose and is returned by `use Config; $Config{path_sep}`. – daxim May 24 '10 at 21:10
  • @daxim - I edited the title, hope it's less ambiguous now – DVK May 25 '10 at 15:37
  • In both Perl and Java forward slashes `/` will work on Windows just as they work on linux/unix/mac. The same is true for loads of command line tools which originate from unix like Ghostscript and TeX. So most of the time you won't need to know the path separator. – MJ Walsh Jan 04 '20 at 20:58

4 Answers4

26

You should not form file paths by hand - instead use File::Spec module:

($volume, $directories,$file) = File::Spec->splitpath( $path );
@dirs = File::Spec->splitdir( $directories );
$path = File::Spec->catdir( @directories );
$path = File::Spec->catfile( @directories, $filename );
DVK
  • 126,886
  • 32
  • 213
  • 327
  • Don't forget splitdir. A more elegant way to work with paths is Path::Class available from CPAN. – Schwern May 24 '10 at 20:14
  • @Schwern - I don't feel comfortable recommending Path::Class as I never used it myself... but I saw recommendations for it elsewhere on SO so I'll check it out. Good point about splitdir - though I'm afraid if I keep going the answer will turn into copy/paste of the POD :) – DVK May 24 '10 at 20:38
  • Path::Class is great, much easier to use than the alternatives. – singingfish May 25 '10 at 01:35
  • @singingfish - it does look fairly easy from surface examination, but to be honest File::Spec is IMHO easy enough to not require a simpler alternative, at least for any tasks I ever needed. But I like Path::Class APIss... clean and readable. – DVK May 25 '10 at 03:01
  • 3
    This really doesn't answer the question though: how to obtain the native path separator with Perl? And it definitely souns like File::Spec should have a method for that, since it definitely knows it, but it doesn't. – Francisco Zarabozo Feb 25 '16 at 19:56
  • Indeed @FranciscoZarabozo, there is no [Perl special variable](http://perldoc.perl.org/perlvar.html) for the path separator. Not sure why not and also why File::Spec doesn't expose it... Perl mysteries. Note that [Python](http://stackoverflow.com/questions/1499019/how-to-get-the-path-separator-in-python) and [Java](http://stackoverflow.com/questions/5971964/file-separator-or-file-pathseparator) both do. – Trutane Jan 20 '17 at 23:39
  • 1
    @Trutane - possibly because Perl was Unix based when created, and a different path separator wasn't a concept at that point. Python and Java were both born into Windows+Unix world. Just my guess, I don't have anything to back that up. – DVK Jan 20 '17 at 23:46
  • @FranciscoZarabozo - I generally hate the X-Y problem answers myself, and hate writing them; but in this case there's just genuinely very little reason to need to know path separator OUTSIDE of any of the tasks that File::Spec already performs for you (the only legit use I can come up with is, building a GUI which shows separator character between file input fields - and even then, using "user friendly" rather than "backend system correct" separator is best anyway. – DVK Jan 20 '17 at 23:48
12

If you really want to get the separator (using only Perl core modules):

my $sep = File::Spec->catfile('', '');

This joins two empty file names with the current system's separator, leaving only the separator.

toolic
  • 57,801
  • 17
  • 75
  • 117
ardnew
  • 2,028
  • 20
  • 29
9

You can use the SL constant in File::Util.

Quai
  • 193
  • 3
0

Before File::Spec, this is what I used. It still works today and it worked on very old perls on every Unix-like and Windows platforms that I've ever encountered.

Basically, the idea is to ask perl what it uses as directory separator char:

$dirSep = ( $ENV{"PATH"} =~ m/;[a-z]:\\/i ) ? '\\' : '/' ; 
print $dirSep;
algn2
  • 11
  • 2