比较PowerShell中的数组变量

cul*_*ter 16 powershell powershell-2.0

我有这个脚本来比较两个文件夹.

$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."
}
Run Code Online (Sandbox Code Playgroud)

如您所见,我比较了同一个文件夹.问题是,它永远不会考虑,数组是相等的.为什么?

Enr*_*lio 33

在PowerShell中,通过枚举数组本身的内容,在表达式中计算指向数组的变量.

例如这个表达式:

$firstFolder | Get-Member
Run Code Online (Sandbox Code Playgroud)

将返回有关System.IO.DirectoryInfo类型的信息,该类型确实是数组中第一个元素的类型$firstFolder.如果要对数组对象本身进行操作,则必须明确告诉PowerShell使用,运算符将对象视为数组.以下表达式:

,$firstFolder | Get-Member
Run Code Online (Sandbox Code Playgroud)

预计将返回有关的信息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
Run Code Online (Sandbox Code Playgroud)

在您的特定情况下,结果将是零长度数组(或者$false如果转换为布尔值),因为该$firstFolder数组包含与变量中的数组不完全匹配的System.IO.DirectoryInfo对象$secondFolder.

你真正想要的是比较两个数组的内容.这是Compare-Object cmdlet派上用场的地方:

Compare-Object $firstFolder $secondFolder -SyncWindow 0
Run Code Online (Sandbox Code Playgroud)

这将返回两个数组之间或数组相等时的差异$null数组.更准确地说,结果数组将包含每个项目的对象,该对象仅存在于一个数组中而不存在于另一个数组中.该-SyncWindow 0参数将使项目在数组中出现的顺序计为差异.

如果你需要的是一个简单的方法来告诉两个数组是否没有进入细节不同的东西是不同的,你可以简单地检查返回的数组的长度比较-对象:

$areEqual = @(Compare-Object $firstFolder $secondFolder -SyncWindow 0).Length -eq 0
Run Code Online (Sandbox Code Playgroud)

请注意我是如何明确告诉PowerShell始终将结果打包到数组中,因为当数组不包含任何差异时,Compare-Object可能会返回$null.


CB.*_*CB. 5

对于这种比较,您必须使用cmdlet compare-object并评估是否存在差异!