1
2
C:\>perl -MFile::Spec::Functions=canonpath -E " say canonpath('project/editor/dev/sp1/kephra/lib/../../../sp3/Kephra/lib/Kephra.pm');"
project\editor\dev\sp3\Kephra\lib\Kephra.pm
$path = File::Spec->canonpath( $path );
1
2
perl -MFile::Spec -E "say File::Spec->canonpath('project/editor/dev/sp1/kephra/lib/../../../sp3/Kephra/lib/Kephra.pm');"
project\editor\dev\sp3\Kephra\lib\Kephra.pm
1
2
perl -MFile::Spec -E "say File::Spec->canonpath('project/editor/dev/sp1/kephra/lib/../../../sp3/Kephra/lib/Kephra.pm');"
project/editor/dev/sp1/kephra/lib/../../../sp3/Kephra/lib/Kephra.pm
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
package path; use strict; use warnings; my $sep; my $sep_not; BEGIN { if($^O=~/linux|os2|vms|unix|epoc/i) { $sep=qr!/!; $sep_not=qr![^/]!; } elsif($^O=~/win/i) { $sep=qr/\\/; $sep_not=qr/[^\\]/; } elsif($^O=~/cygwin/i) { $sep=qr'[/\\]'; $sep_not=qr'[^/\\]'; } elsif($^O=~/mac/i) { $sep=qr!:!; $sep_not=qr![^:]!; } else { $sep=qr([/\\:]); $sep_not=qr([^/\\:]); } } sub clean($) { my $path=shift; 1 while( $path=~s!$sep($sep)!$1!gs ); 1 while( $path=~s!(^|$sep)\.$sep!$1!s ); 1 while( $path=~s!$sep$sep_not*$sep\.\.!!s ); 1 while( $path=~s!^$sep\.\.?(?=$sep)!!s ); 1 while( $path=~s!^\.$sep!!s ); 1 while( $path=~s!($sep)\.$!$1!s ); return $path; } sub strip($) { my $path=shift; 1 while( $path=~s!^\.\.?$sep!!s ); 1 while( $path=~s!(^|$sep)\.\.?(?=$sep|$)!$1!s ); 1 while( $path=~s!$sep($sep)!$1!gs ); return $path; } 1;
2013-07-01T20:32:02 lichtkindkennt ihr etwas das mir
"project/editor/dev/sp1/kephra/lib/../../../sp3/Kephra/lib/Kephra.pm"
zu
"project/editor/dev/sp3/Kephra/lib/Kephra.pm"
auflöst. Hatte erwatet das canonpath von File::Spec das kann aber offensichtlich nicht.
Quotecanonpath
No physical check on the filesystem, but a logical cleanup of a path.
$cpath = File::Spec->canonpath( $path ) ;
Note that this does *not* collapse x/../y sections into y. This is by design. If /foo on your system is a symlink to /bar/baz, then /foo/../quux is actually /bar/quux, not /quux as a naive ../-removal would give you. If you want to do this kind of processing, you probably want Cwd's realpath() function to actually traverse the filesystem cleaning up paths like this.
2013-07-03T13:28:05 LinuxerWarum tut dann canonpath() auf Windows genau das, was es laut Doku nicht tun soll?
2013-07-03T13:28:05 LinuxerDeine Anforderungsbeschreibung ist auch recht dürftig. Willst Du nur die ".." ersetzt haben?
2013-07-03T13:28:05 LinuxerOder willst Du auch den Check im Dateisystem, ob der Pfad gültig/vorhanden ist?
2013-07-03T13:28:05 LinuxerPS: Und was ist mit dem von mir anfangs genannten CWD::realpath()? Dazu kam gar keine Antwort?
2013-07-03T14:57:47 lichtkind2013-07-03T13:28:05 LinuxerWarum tut dann canonpath() auf Windows genau das, was es laut Doku nicht tun soll?
Das ist eine sehr gute Frage.
2013-07-05T12:21:42 GwenDragonWen man kein NTFS...? Himmel, NTFS gibt es seit mindestens 15 Jahren, das kann nicht wirklich das Argument sein. ;)
2013-07-03T13:28:05 LinuxerNa, Danke. :-(
2013-07-03T13:28:05 LinuxerWarum tut dann canonpath() auf Windows genau das, was es laut Doku nicht tun soll?
Beispiele habe ich weiter oben ja schon gebracht.
QuoteDem widerspricht ferner, dass das Ergebnis plattformabhängig ist, und auch deine Beobachtung, dass sich der Kode massiv zwischen Windows 7 und Fedora unterscheidet."Note that this does *not* collapse x/../y sections into y. This is by design."
preprocess => sub { .. }