Сравнение переменных массива в PowerShell - PullRequest
15 голосов
/ 07 марта 2012

У меня есть этот скрипт для сравнения двух папок.

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

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

Ответы [ 3 ]

32 голосов
/ 07 марта 2012

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

Например, это выражение:

$firstFolder | Get-Member

вернет информацию о типе System.IO.DirectoryInfo , который действительно является типом элемента first в массиве $firstFolder. Если вы хотите работать с самим объектом массива, вы должны явно указать PowerShell обрабатывать объект как массив с помощью оператора ,. Следующее выражение:

,$firstFolder | Get-Member

ожидаемо вернет информацию о System.Object[].

Однако, когда оператор -eq используется между двумя переменными массива, все немного по-другому. Фактически PowerShell будет перечислять только массив с левой стороны 1020 * и сравнивать каждый элемент с массивом с правой стороны в целом . Результатом будет массив совпадающих элементов или вообще ничего при отсутствии совпадений. Например:

$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, если приведен к логическому ), поскольку массив $firstFolder содержит System.IO.DirectoryInfo объекты, которые не совсем совпадают с массивом в переменной $secondFolder.

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

Compare-Object $firstFolder $secondFolder -SyncWindow 0

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

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

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

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

5 голосов
/ 07 марта 2012

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

0 голосов
/ 02 июля 2019

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

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

arrayequal $a $b

True
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...