2012-03-07 135 views
12

私はこのスクリプトを使用して2つのフォルダを比較しています。PowerShellでの配列変数の比較

$firstfolder = Get-ChildItem C:\firstfolder 
$secondfolder = Get-ChildItem C:\firstfolder 

if ($firstfolder -eq $secondfolder) { 
Write-Host "Folders are the same." 
} else { 
    Write-Host "Error: Doesn't match." 
} 

ご覧のとおり、同じフォルダを比較します。問題は、配列が等しいことを決して考慮しないことです。どうして?

答えて

25

PowerShellでは、配列を指す変数は、配列自体の内容を列挙することによって式で評価されます。

$firstFolder | Get-Member 

実際$firstFolderアレイにおける最初素子の一種であるSystem.IO.DirectoryInfoタイプに関する情報を返します。この表現は、例えば

。配列オブジェクト自体を操作する場合は、演算子,を使用して、オブジェクトを配列として扱うように明示的にPowerShellに指示する必要があります。次の式は、System.Object[]についての情報を期待して返します。

,$firstFolder | Get-Member 

ただし、-eq演算子を2つの配列変数の間で使用すると、少し異なります。実際、PowerShellは、のアレイを列挙しての列のみを列挙し、各項目を右側の配列と全体として比較します。結果は一致するアイテムの配列または全く一致しない場合はとなります。例えば:(booleanにキャスト場合又は$false$firstFolderアレイはかなり$secondFolderでアレイに一致しないSystem.IO.DirectoryInfoオブジェクトが含まれているので、あなたの特定の場合において

$a = 1..5 
$b = 1..5 
$a -eq $b   # returns zero-length array 
[bool]($a -eq $b) # returns $false 
$a -eq 3   # returns 3 

、結果は長さゼロの配列であろう変数。

の内容と、両方の配列のをお互いに比較してみてください。配列が等しい場合

Compare-Object $firstFolder $secondFolder -SyncWindow 0 

これは、違いの配列二つの配列または$null間を返します。Compare-Object cmdletが便利になるところです。より正確には、結果の配列には、1つの配列にのみ存在し、他の配列には存在しない各項目のオブジェクトが含まれます。 -SyncWindow 0引数は、配列内に表示される項目の順序を差異としてカウントします。

あなたが必要とするすべては、あなたは、単にCompare-Objectによって返される配列の長さを確認することができ、二つの配列が異なっているものをの詳細に行かずに異なっているかどうかを伝えるための簡単な方法である場合:

$areEqual = @(Compare-Object $firstFolder $secondFolder -SyncWindow 0).Length -eq 0 

Compare-Objectは、配列に相違がない場合、$nullを返す可能性があるため、結果を配列に常にパッケージ化するようPowerShellに明示したことに注目してください。あなたはコマンドレットcompare-objectを使用して、そこに違いはありますかどうかを評価しなければならない比較のこの種の

+0

、エンリコ、ありがとうございました。内容の代わりに配列の名前を比較するという意味ですか? '-eq'オペレータ@culter – culter

+0

は、実際には各配列の最初のオブジェクトを比較します。私の更新された答えを見てください。 –

+0

は、あなたが答え、エンリコを排出いただきありがとうございます。それは完全に動作します。しかし、あなたが書いたように、-eq演算子は各配列の最初のオブジェクトを比較します。なぜ、同じフォルダを比較したときにfalseを返したのですか? – culter

4