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

I have the following code
use strict; use warnings; my( $xlink,@xlinkpaths ); my @xlinks = (`cmd to get xlinks`) ; my $op="/"; foreach $xlink (@xlinks) { $xlink =~ m{incl -s DS_Dalmore_Int /. /|\\.\\(.+)}; push @xlinkpaths, $1 . $op; }
The output stored in @xlinks looks like this in mac/linux
incl -s streamname /./abc/def xlink /./abc/def from streamname incl -s streamname /./xyz/qwen/defs/asd xlink /./xyzz/qwen/defs/asd from streamname
</code> The output stored in @xlinks looks like this in windows
incl -s streamname \.\abc/def xlink /./abc/def from streamname incl -s streamname \.\xyz/qwen/defs/asd xlink /./xyzz/qwen/defs/asd from streamname
So my final array looks like this in mac/linux, which looks good.
@xlinkpaths = ( "abc/def/", "xyzz/qwen/defs/asd/", );
But the output in windows shows like
@xlinkpaths = ( "abc/def\", "xyzz/qwen/defs/asd\", );
How can I append \ or / in my $op differently to my final array @xlinkpaths based on windows or linux?

Replies are listed 'Best First'.
Re: Perl appending \ or / based on windows or linux
by kennethk (Abbot) on Oct 07, 2014 at 00:39 UTC

    Alternatively, use CORE module File::Spec, and let Perl handle it.


    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

      I second this.

      use File::Spec::Functions; my $path = catfile("xyzz", "qwen", "defs", "asd"); # $path is now "xyzz/qwen/defs/asd" on most systems, # but on Windows it'll have backslashes instead # and I think on old MacOS Classic systems it would # have colons or something. Don't ask about VMS.

      (Note: This is a reply equally to kennethk, jonadab, and anon)

      sravs448 wants to append a trailing slash (whether or not that's an XY Problem is another topic). Unfortunately, File::Spec, despite being the core module to handle file/pathnames properly and portably, does not provide a method to do this. Most likely that's because "append a trailing slash" is not really a portable concept across all these supported OSes.

      As long as the script is limited to a known set of OSes, McA's suggestion above is probably better in this case.

      If there was a solution with a core module (perhaps I've missed something*), that'd make me happy, since I've faced this problem myself before. (Back when I had this problem I didn't find a decent CPAN module either.)

        dasgar's point about regexing File::Spec aside, it seems like any application that requires a trailing directory separator is really just not using File::Spec enough. Maybe it's my lack of imagination, but short of this literal spec (as you say, XY Problem) I cannot come up with an appropriate use case.

        #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

        You should be able to use a combination of File::Spec and a regex to dynamically determine what the seperation character is - provided that the regex contains all possible seperation characters.

        use strict; use warnings; use File::Spec::Functions qw(:ALL); use feature 'say'; my $testpath = catdir('foo','bar'); #say $testpath; my $sepchar; ($sepchar) = ($testpath =~ m/(\\|\/)/); say $sepchar;

        Not sure that this is any better than using $^O to determine the seperation character, but it one possible method using a core module. In either case, you still need to know the valid seperation characters for OSes that you intend to support. I guess the only advantage of the code above over using $^O is that you don't need to know the values of $^O for each OS.

Re: Perl appending \ or / based on windows or linux
by McA (Priest) on Oct 06, 2014 at 21:57 UTC

    Hi,

    probably with something like that:

    my %seperators = ( 'Linux' => '/', 'MSWin32' => '\\', 'MacOS' => '/', ); my $op = quotemeta($seperators{$^O} || '/');

    Regards
    McA

      That's

      my %separators = ( linux => '/', MSWin32 => '\\', darwin => '/', );

      There's other possible values, but the script could be restricted to run on only the "supported" platforms via

      die "This script doesn't yet run on $^O\n" unless $separators{$^O};
Re: Perl appending \ or / based on windows or linux
by Anonymous Monk on Oct 06, 2014 at 22:23 UTC

    Running your code against your shown input does not produce the output you are showing. Please fix the input, code, and/or output.

Re: Perl appending \ or / based on windows or linux
by Anonymous Monk on Oct 07, 2014 at 14:06 UTC
    File::Spec is the best way to do it.
Re: Perl appending \ or / based on windows or linux
by Anonymous Monk on Oct 08, 2014 at 02:18 UTC
    I guess this just might be an object-lesson about the perils of jumping too-quickly to "how to do <<this>>" (as though you really were somehow the first person in the universe who needed to overcome a particular problem) ... instead of taking a double-step backward to consider, "what, exactly, is the problem that I am attempting to solve?" We literally jump to the conclusion, specifically the first "conclusion" that comes to our minds, and waste much time because we don't think outside the box.