Подтвердить что ты не робот

Сравнение переменных массива в PowerShell

У меня есть этот script, чтобы сравнить две папки.

$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."
}

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

4b9b3361

Ответ 1

В 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, когда массивы дона 't содержит какие-либо различия.

Ответ 2

Для такого рода сравнений вы должны использовать cmdlet compare-object и оценить, есть ли различия или нет!

Ответ 3

Может быть как то так

function arrayequal($a, $b) {
  -not (compare $a $b)
}

arrayequal $a $b

True