2012-03-07 98 views
12

我有這個腳本來比較兩個文件夾。在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 

將返回有關System.IO.DirectoryInfo類型,這的確是$firstFolder陣列中的第一元件的類型的信息。如果你想操作數組對象本身,你必須明確地告訴PowerShell通過使用,運算符將對象作爲數組處理。下面的表達式:

,$firstFolder | Get-Member 

會果然返回有關System.Object[]信息。

但是,當在兩個數組變量之間使用-eq運算符時,事情有點不同。事實上,PowerShell將只列舉左側的陣列,並將每個項目與整個右側的陣列進行比較。結果將是匹配項數組什麼都沒有當沒有匹配時。例如:

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

在您的特定情況下,其結果將是零長度的陣列(或者如果$false澆鑄到boolean)由於$firstFolder數組包含System.IO.DirectoryInfo對象不太在$secondFolder陣列匹配變量。

你真正想要的是將兩個陣列的內容相互比較。這就是Compare-Object cmdlet派上用場:

Compare-Object $firstFolder $secondFolder -SyncWindow 0 

當數組相等這將返回一個陣列的差異兩個陣列或$null之間。更確切地說,結果數組將包含一個對象,每個對象只存在於一個數組中,而不存在於另一個數組中。參數-SyncWindow 0將使項目在數組中顯示的順序成爲差異。

如果你需要的是一個簡單的方法來告訴兩個數組是否不同沒有進入的什麼是不同的細節,你可以簡單地檢查由Compare-Object返回數組的長度:

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

請注意,我明確告訴PowerShell總是將結果打包到數組中,因爲當數組不包含任何差異時,Compare-Object可能會返回$null

+0

謝謝Enrico。你的意思是,它比較了數組的名稱而不是內容? – culter 2012-03-07 09:11:20

+0

@culter'-eq'操作符實際上比較每個數組中的第一個對象。看到我更新的答案。 – 2012-03-07 10:03:41

+0

謝謝你用盡了答案,恩里科。它完美的作品。但是正如你寫的,-eq運算符比較每個數組的第一個對象,爲什麼當我比較相同的文件夾時它返回false? – culter 2012-03-07 10:16:58

4

對於這種比較,您必須使用cmdlet compare-object並評估是否存在差異!