2012-03-07 96 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并评估是否存在差异!