views:

358

answers:

4

Scenario is:

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 my own path for the $pwd e.g. I want to be able to print out, for e.g. a path of c:\temp\files 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

??

Thanks in advance

A: 

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.

tyranid
+2  A: 

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
}
stej
The -replace operator allows usage of regexes that are case insensitive e.g. `$_.Fullname -replace [regex]::escape($from),$to`
Keith Hill
Oh, I always learn something new. Thx! ;)
stej
+1  A: 

This works pretty well for me:

gci c:\dev\deploy -r -name | %{"c:\temp\$_"}
Keith Hill
+1  A: 

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* }
Jordij