2012-03-07 24 views
12

Tengo esta secuencia de comandos para comparar dos carpetas.Comparación de variables de matriz en 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." 
} 

Como puede ver, comparo la misma carpeta. El problema es que nunca considerará que las matrices son iguales. ¿Por qué?

Respuesta

25

En PowerShell, las variables que apuntan a matrices se evalúan en expresiones enumerando los contenidos de las matrices.

Por ejemplo esta expresión:

$firstFolder | Get-Member 

devolverá información sobre el tipo System.IO.DirectoryInfo, que de hecho es el tipo de la primera elemento en la matriz $firstFolder. Si desea operar en el objeto de matriz en sí, debe decirle explícitamente a PowerShell que trate el objeto como una matriz usando el operador ,. La siguiente expresión:

,$firstFolder | Get-Member 

será previsiblemente devolver información sobre System.Object[].

Sin embargo, cuando el operador -eq se utiliza entre dos variables de matriz, las cosas son un poco diferentes. De hecho, PowerShell enumerará solo la matriz en el lado izquierdo y comparará cada elemento con el conjunto en el lado derecho como un todo. El resultado será una matriz de elementos coincidentes o nada en absoluto cuando no hay coincidencias. Por ejemplo:

$a = 1..5 
$b = 1..5 
$a -eq $b   # returns zero-length array 
[bool]($a -eq $b) # returns $false 
$a -eq 3   # returns 3 

En su caso particular, el resultado será de longitud cero array (o $false si fundido a una boolean) desde la matriz $firstFolder contiene System.IO.DirectoryInfo objetos que no se ajusta exactamente con la matriz en el $secondFolder variable.

Lo que realmente quiere es comparar el contenido de ambas matrices una contra la otra. Aquí es donde el Compare-Object cmdlet viene muy bien:

Compare-Object $firstFolder $secondFolder -SyncWindow 0 

Esto devolverá una tabla de diferencias entre las dos matrices o $null cuando los arreglos son iguales. Más precisamente, la matriz resultante contendrá un objeto para cada elemento que existe solo en una matriz y no en la otra. El argumento -SyncWindow 0 hará que el orden en que aparecen los elementos en las matrices cuente como una diferencia.

Si todo lo que necesita es una forma sencilla de decir si los dos conjuntos son diferentes, sin entrar en los detalles de lo es diferente, sólo tiene que comprobar la longitud de la matriz devuelta por Compare-Object:

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

Observe cómo le dije explícitamente a PowerShell que siempre empaquete los resultados en una matriz, ya que Compare-Object puede devolver $null cuando las matrices no contienen ninguna diferencia.

+0

Gracias, Enrico. ¿Quiso decir que compara los nombres de las matrices en lugar de su contenido? – culter

+0

@culter El operador '-eq' en realidad compara el primer objeto en cada conjunto. Ver mi respuesta actualizada. –

+0

Gracias por su agotadora respuesta, Enrico. Funciona perfectamente Pero mientras escribía, el operador -eq compara el primer objeto de cada matriz, ¿por qué devolvió falso cuando comparé la misma carpeta? – culter

4

Para este tipo de comparaciones, debe usar el cmdlet compare-object y evaluar si hay diferencias o no.

Cuestiones relacionadas