开发者

Powershell: subtract $pwd from $file.Fullname

Given the following files:

c:\dev\deploy\file1.txt
c:\dev\deploy\file2.txt
c:\dev\deploy\file3.txt
c:\dev\deploy\lib\do1.dll
c:\dev\deploy\lib\do2.dll

e.g. if $pwd is the following

c:\dev\deploy

running the statement

$files = get-childitem

I want to take this list and using foreach ($file in $files) I want to substitute 开发者_StackOverflowmy own path for the $pwd e.g. I want to print c:\temp\files like the following:

c:\temp\files\file1.txt
c:\temp\files\file2.txt
c:\temp\files\file3.txt
c:\temp\files\lib\do1.dll
c:\temp\files\lib\do2.dll

How can I peform this i.e.

A = c:\dev\deploy\file1.txt - c:\dev\deploy\
B = c:\temp\files\ + A

giving B = c:\temp\files\file1.txt

?


I would use filter here and consider piping the files like this:

filter rebase($from=($pwd.Path), $to)  {
    $_.FullName.Replace($from, $to)
}

You can call it like this:

Get-ChildItem C:\dev\deploy | rebase -from C:\dev\deploy -to C:\temp\files\
Get-ChildItem | rebase -from (Get-Location).path -to C:\temp\files\
Get-ChildItem | rebase -to C:\temp\files\

Note that the replacing is case sensitive.


In case you would need case insensitive replace, regexes would help: (edit based on Keith's comment. Thanks Keith!)

filter cirebase($from=($pwd.Path), $to)  {
    $_.Fullname -replace [regex]::Escape($from), $to
}


There's a cmdlet for that, Split-Path, the -leaf option gives you the file name. There's also Join-Path, so you can try something like this:

dir c:\dev\deploy | % {join-path c:\temp\files (split-path $_ -leaf)} | % { *action_to_take* }


How about something like:

function global:RelativePath
{
    param
    (
        [string]$path = $(throw "Missing: path"),
        [string]$basepath = $(throw "Missing: base path")
    )

    return [system.io.path]::GetFullPath($path).SubString([system.io.path]::GetFullPath($basepath).Length + 1)
}    

$files = get-childitem Desktop\*.*

foreach($f in $files)
{
    $path = join-path "C:\somepath" (RelativePath $f.ToString() $pwd.ToString())
    $path | out-host
}

I took the simple relative path from here although there is some problems with it, but as you only want to handle paths below your working directory it should be okay.


This works pretty well for me:

gci c:\dev\deploy -r -name | %{"c:\temp\$_"}


The accepted answer only works without Sub-Folders

if you need to "convert" Sub-Folders, the Answer of @stej is better.

Here my Version:

 Get-ChildItem -Recurse | ForEach-Object { $_.Fullname.Replace('D:\Work\Test\Release', 'C:\temp\files') }

Note: .Replace doesn't need to be escaped

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜