2011-08-03 68 views
3

Powershellを使用して、あるフォルダから別のフォルダにフォルダ(およびサブフォルダまたはさらに深いフォルダ)をスキャンして移動したいとします。Get-ChildItemの結果はPowershellの相対パスのように見えます

現在、私はこのコマンドのパイプを使用しています。得られた結果は.\sub\WORKに対して相対的であるため、

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

残念ながら、それは動作しません、彼らが移動し、アイテムを移動しようとするときは、フォルダをカレントフォルダにないと文句を言い:

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を使用する必要はありません)

私が答えだ主な理由はこれです1つ: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が文字列にGet-ChildItemからFileInfoを変換する必要がある場合、それは異なる結果が得られます。それはMove-Itemの引数として$_を使用したときに発生しました。かなり悪い。

私はこの動作を報告するバグがあると思います。

+0

私にはバグのように見えましたが、私のパワーシェルの経験はあまりにも低すぎると言いました。私が '-include "* OK"'を 'Get-ChildItem'に追加すると、それも機能します。あなたの説明はとても役に立ちました。 –

+0

あなたが持っているものでなければ、とにかくToString()に頼るべきではありません。 :) – JasonMArcher

3

オブジェクトがパイプラインの下で文字列の代わりにパイプされていることが間違いありません。これは、より柔軟である点で優れています。欠点は、使用するオブジェクトのどのプロパティがシステム設計者の慈悲にあるのかを明示的にシステムに伝えていない場合です。あなたがソースを指定していないときなど、私はちょうどPSPathが自動的にコピー項目で使用されていることをlearn't

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

移動-アイテム:明示的にしたいプロパティが役立つシステムを伝えるかどうかを確認パイプラインで、何かのようになる:

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

(簡略化した例)

がうまくいくと、それはソースを決定するために、渡されたオブジェクトのPSPathを使用します。


Get-ChildItemリターンはあなたが言ったように、あなたがオブジェクトを提供しているものを見るためにGet-Memberを使用することができますオブジェクトので(つまり、そのプロパティとメソッドについて知っている)

Get-ChileItem path | Get-Member 

あなたはそのフルネームを見ることができましたあなたが使用できるプロパティの1つです。

0

ここが私の仕事です。

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