Сравнение переменных массива в 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."
}

Как вы можете видеть, я сравниваю ту же папку. Проблема в том, что он никогда не будет считать, что массивы равны. Почему?

2 ответов


в PowerShell переменные, указывающие на массивы, оцениваются в выражениях путем перечисления содержимого самих массивов.

например такое выражение:

$firstFolder | Get-Member

вернет информацию о Система.ИО.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 массив содержит Система.ИО.DirectoryInfo объекты, которые не совсем соответствуют массиву в $secondFolder переменной.

что вы действительно хотите, чтобы сравнить содержание обоих массивов друг против друга. Это где командлет Compare-Object пригождается:

Compare-Object $firstFolder $secondFolder -SyncWindow 0

это вернет массив различия между двумя массивами или $null если массивы равны. Точнее, результирующий массив будет содержать объект для каждого элемента, который существует только в одном массиве, а не другой. The -SyncWindow 0 аргумент сделает порядок, в котором элементы появляются в массивах, засчитывается как разница.

если все, что вам нужно, это простой способ скажите, отличаются ли два массива, не вдаваясь в детали что отличается, Вы можете просто проверить длину массива, возвращаемого Сравнить-Объект:

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

обратите внимание, как я явно сказал PowerShell всегда упаковывать результаты в массив, так как Сравнить-Объект может возвратить $null когда массивы не содержат никаких различий.


для такого рода сравнений необходимо использовать командлет compare-object и оценить, есть ли различия или нет!