Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Perl appending \ or / based on windows or linux

by sravs448 (Acolyte)
on Oct 06, 2014 at 21:20 UTC ( [id://1103015]=perlquestion: print w/replies, xml ) Need Help??

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.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1103015]
Approved by tobyink
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (6)
As of 2024-04-19 16:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found