Getting relative path from absolute path in PowerShell

梦想与她 提交于 2019-12-24 00:19:51

问题


The problem

You have an absolute path, but you want it to be relative to another path.

Example:

P:/SO/data/database.txt

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

I have already found the Stack Overflow question How to convert absolute path to relative path in PowerShell?.

One answer links to an already developed Cmdlet, but this one didn't work for me. And the trick using Set/Get-Location requires the paths to exist.


回答1:


The solution

I found an answer from Gordon written in PHP: Getting relative path from absolute path in PHP.

Here is my port to 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;
}

Attention: - You From path has to end with a slash!

Example

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


来源:https://stackoverflow.com/questions/13239620/getting-relative-path-from-absolute-path-in-powershell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!