2

問題

絶対パスがありますが、別のパスを基準にする必要があります。

例:

P:/SO/data/database.txt

--> Now we want the filename to be relative to: P:/SO/team/lists/
../../data/database.txt

PowerShellで絶対パスを相対パスに変換する方法についてのスタックオーバーフローの質問をすでに見つけました。。

1つの答えは、すでに開発されたコマンドレットにリンクしていますが、これは私には機能しませんでした。そして、を使用するトリックSet/Get-Locationには、パスが存在する必要があります。

4

1 に答える 1

1

ソリューション

PHPで書かれたGordonからの答えを見つけました: PHPの絶対パスから相対パスを取得します

これがPowerShellへの私の移植です:

<# This is probably not the best code I've ever written, but
   I think it should be readable for most (advanced) users.

   I will wrap this function into a Cmdlet when I have time to do it.
   Feel free to edit this answer and improve it!
#>
function getRelativePath([string]$from, [string]$to, [string]$joinSlash='/') {

    $from = $from -replace "(\\)", "/";
    $to = $to -replace "(\\)", "/";

    $fromArr = New-Object System.Collections.ArrayList;
    $fromArr.AddRange($from.Split("/"));

    $relPath = New-Object System.Collections.ArrayList;
    $relPath.AddRange($to.Split("/"));


    $toArr = New-Object System.Collections.ArrayList;
    $toArr.AddRange($to.Split("/"));

    for ($i=0; $i -lt $fromArr.Count; $i++) {
        $dir = $fromArr[$i];

        # Find first non-matching directory
        if ($dir.Equals($toArr[$i])) {
            # ignore this directory
            $relPath.RemoveAt(0);
        }
        else {
            # Get number of remaining directories to $from
            $remaining = $fromArr.Count - $i;
            if ($remaining -gt 1) {
                # Add traversals up to first matching directory
                $padLength = ($relPath.Count + $remaining - 1);

                # Emulate array_pad() from PHP
                for (; $relPath.Count -ne ($padLength);) {
                    $relPath.Insert(0, "..");
                }
                break;
            }
            else {
                $relPath[0] = "./" + $relPath[0];
            }
        }
    }
    return $relPath -Join $joinSlash;
}

注意:-You Fromパスはスラッシュで終了する必要があります!

getRelativePath -From "P:/SO/team/lists/" -To "P:/SO/data/database.txt";
--> ../../data/database.txt

getRelativePath -From "C:/Windows/System32/" -To "C:/Users/ComFreek/Desktop/SO.txt";
--> ../../Users/ComFreek/Desktop/SO.txt
于 2012-11-05T20:12:47.037 に答える