Get-ChildItem结果看起来像Powershell中的相对路径

时间:2011-08-03 14:53:24

标签: powershell move

我想使用Powershell扫描并将文件夹(和子文件夹甚至更深)从一个文件夹移动到另一个文件夹。

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

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

不幸的是它不起作用,因为找到的结果是相对于.\sub\WORK,当试图移动它们时Move-Item会抱怨文件夹不在当前文件夹中:

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 个答案:

答案 0 :(得分: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的参数时发生这种情况。非常糟糕。

我认为存在报告此行为的错误。

答案 1 :(得分:3)

你说对象是管道而不是字符串。这很好,因为它更灵活。缺点是,如果您没有明确告诉系统要使用的对象属性,那么您将受系统设计人员的支配。看看是否明确告诉系统您想要的属性将有所帮助:

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

答案 2 :(得分:1)

我只是不知道当你没有在管道中指定源时,PSPath会自动用在Copy-Item,Move-Item等中,所以类似于:

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

(简化示例)

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


由于Get-ChildItem返回了你所说的对象,你可以使用Get-Member来查看对象提供的内容(了解其属性和方法)

 Get-ChileItem path | Get-Member

您可以看到FullName是您可以使用的属性之一。

答案 3 :(得分:0)

这对我有用。

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