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
精彩评论