简体   繁体   English

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

[英]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

eg if $pwd is the following例如,如果 $pwd 如下

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 eg I want to print c:\\temp\\files like the following:我想使用这个列表并使用foreach ($file in $files)我想用我自己的路径替换$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

How can I peform this ie我怎么能执行这个,即

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
}

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.我从这里采用了简单的相对路径,尽管它存在一些问题,但由于您只想处理工作目录下的路径,所以应该没问题。

这对我来说非常有效:

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

There's a cmdlet for that, Split-Path , the -leaf option gives you the file name.有一个 cmdlet, Split-Path-leaf选项为您提供文件名。 There's also Join-Path , so you can try something like this:还有Join-Path ,所以你可以尝试这样的事情:

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

The accepted answer only works without Sub-Folders接受的答案仅适用于没有子文件夹

if you need to "convert" Sub-Folders, the Answer of @stej is better.如果您需要“转换”子文件夹,@stej 的答案更好。

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注意: .Replace 不需要转义

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM