2011-08-03 50 views
3

我想使用Powershell扫描并移动文件夹(和子文件夹或更深层)从一个文件夹到另一个文件夹。Get-ChildItem结果看起来像Powershell中的相对路径

目前我正在使用这个命令管道。

Get-ChildItem -recurse -path sub\WORK -filter "* OK" | Where-Object { $_.PSIsContainer } | foreach { Move-Item -path $_ -destination sub\OK } 

遗憾的是它不工作,因为找到的结果是相对于.\sub\WORK,试图转移它们的布展项目抱怨说,文件夹是不是在当前文件夹时:

Move-Item : Cannot find path 'C:\TMP\2011-12-12 test 2 OK' because it does not exist. 

我期待$ _将包含:'C:\TMP\sub\WORK\2011-12-12 test 2 OK',因为这些是Powershell中的对象,并且没有像Linux中的字符串。

回答

4

如果您使用Get-ChildItem,请非常小心。最好的办法是管对象Move-Item,你不必去想更多:

Get-ChildItem -recurse -path sub\WORK -filter "* OK" | Where-Object { $_.PSIsContainer } | Move-Item -destination sub\OK 

(无需使用Foreach-Object

为什么我回答是这种情况的主要原因一个:Get-ChildItem根据参数不同地构造对象。请看例子:

PS C:\prgs\tools\Console2> gci -include * | % { "$_" } | select -fir 5 
C:\prgs\tools\Console2\-verbose 
C:\prgs\tools\Console2\1UpdateDataRepositoryServices.ps1 
C:\prgs\tools\Console2\22-52-59.10o52l 
C:\prgs\tools\Console2\2jvcelis.ps1 
C:\prgs\tools\Console2\a 
PS C:\prgs\tools\Console2> gci | % { "$_" } | select -fir 5 
-verbose 
1UpdateDataRepositoryServices.ps1 
22-52-59.10o52l 
2jvcelis.ps1 
a 

然后,如果你在一个周期中使用$_和PowerShell需要FileInfoGet-ChildItem转换为字符串,它提供了不同的结果。当您使用$_作为Move-Item的参数时会发生这种情况。相当糟糕。

我认为有一个报告此行为的错误。

+0

这对我来说看起来像一个bug,但我的powershell经验有点太低,不提这样的事情。如果我在'Get-ChildItem'中添加'-include'* OK'',那么它也可以工作。你的解释非常有帮助。 –

+0

好吧,你不应该依赖于ToString(),除非你拥有所有的东西。 :) – JasonMArcher

3

你是正确的,对象正在管道而不是字符串管道。这很好,因为它更加灵活。缺点是如果你没有明确地告诉系统哪个对象的属性使用你受制于系统设计者的摆布。看看是否明确告诉系统你想帮助属性:

Get-ChildItem -recurse -path sub\WORK -filter "* OK" | Where-Object { $_.PSIsContainer } | foreach { Move-Item -path $_.Fullname -destination sub\OK } 
1

我只是learn't的PSPath被复制,项目自动使用,布展等项目时不指定源在管道中,因此这样的:

gci .\sub\Work | move-item -Destination .\sub\OK 

(简化的示例)

将工作,它会使用传递的对象的PSPath来确定源。


由于Get-ChildItem返回一个对象像你说的,你可以使用Get-Member看什么对象所提供的(也就是了解它的属性和方法)

Get-ChileItem path | Get-Member 

你可以看到,全名是您可以使用的属性之一。

0

这是什么为我工作。

Get-ChildItem -Path .\ -Recurse -filter "* OK" | %{Join-Path -Path $_.Directory -ChildPath $_.Name } | Move-Item -Destination sub\OK