Powershell:从$file.Fullname中减去$pwd

Powershell:从$file.Fullname中减去$pwd,powershell,path,split,Powershell,Path,Split,给定以下文件: 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.如果$pwd为以下值 c:\dev\deploy 运行语句 $files = get-childitem 我想获取此列表并使用foreach($files中的file)我想用我自己的路径替换$pwd,例如,我想打印c:\

给定以下文件:

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.如果$pwd为以下值

c:\dev\deploy
运行语句

$files = get-childitem
我想获取此列表并使用
foreach($files中的file)
我想用我自己的路径替换
$pwd
,例如,我想打印
c:\temp\files
,如下所示:

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
我怎样才能做到这一点,即

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

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

比如:

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
}

我使用了简单的相对路径,虽然它存在一些问题,但是由于您只想处理工作目录下面的路径,所以应该是好的。

< P>我将使用筛选器,并考虑将文件这样排列:

filter rebase($from=($pwd.Path), $to)  {
    $_.FullName.Replace($from, $to)
}
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\
dir c:\dev\deploy | % {join-path c:\temp\files (split-path $_ -leaf)} | % { *action_to_take* }
你可以这样称呼它:

filter rebase($from=($pwd.Path), $to)  {
    $_.FullName.Replace($from, $to)
}
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\
dir c:\dev\deploy | % {join-path c:\temp\files (split-path $_ -leaf)} | % { *action_to_take* }
请注意,替换是区分大小写的


如果需要不区分大小写的替换,正则表达式将有助于: (根据基思的评论编辑。谢谢基思!)


这对我来说非常有效:

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

有一个cmdlet,Split Path-leaf选项为您提供文件名。还有连接路径,因此您可以尝试以下方法:

filter rebase($from=($pwd.Path), $to)  {
    $_.FullName.Replace($from, $to)
}
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\
dir c:\dev\deploy | % {join-path c:\temp\files (split-path $_ -leaf)} | % { *action_to_take* }

接受的答案仅在没有子文件夹的情况下有效

如果您需要“转换”子文件夹,@stej的答案更好

以下是我的版本:

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

注意:.Replace不需要进行转义

这个-Replace操作符允许使用不区分大小写的正则表达式,例如
$\u全名-Replace[regex]::escape($from),$to
这不是他们要求的,他们想要的是递归解决方案