2012-03-07 44 views
12

Tôi có tập lệnh này để so sánh hai thư mục.So sánh các biến mảng trong 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." 
} 

Như bạn có thể thấy, tôi so sánh cùng một thư mục. Vấn đề là, nó sẽ không bao giờ xem xét, rằng các mảng là như nhau. Tại sao?

Trả lời

25

Trong PowerShell, các biến trỏ đến mảng được đánh giá trong biểu thức bằng cách liệt kê nội dung của các mảng.

Ví dụ biểu thức này:

$firstFolder | Get-Member 

sẽ trở lại thông tin về loại System.IO.DirectoryInfo, mà thực sự là kiểu của phần tử đầu tiêntrong mảng $firstFolder. Nếu bạn muốn hoạt động trên chính đối tượng mảng, bạn phải cho PowerShell biết rõ ràng để xử lý đối tượng dưới dạng mảng bằng cách sử dụng toán tử ,. Biểu thức sau:

,$firstFolder | Get-Member 

dự kiến ​​sẽ trả về thông tin về System.Object[].

Tuy nhiên, khi toán tử -eq được sử dụng giữa hai biến mảng, mọi thứ hơi khác một chút. PowerShell sẽ, trên thực tế, chỉ liệt kê mảng ở bên trái bên trái và so sánh từng mục với mảng ở bên phải là toàn bộ. Kết quả sẽ là một mảng các mục phù hợp hoặc không có gì ở tất cả khi không có kết quả phù hợp. Ví dụ:

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

Trong trường hợp cụ thể của bạn, kết quả sẽ là zero-length mảng (hoặc $false nếu Casted đến một boolean) kể từ khi mảng $firstFolder chứa System.IO.DirectoryInfo đối tượng mà không khá phù hợp với mảng trong $secondFolder biến.

Điều bạn thực sự muốn là so sánh nội dung của cả hai mảng với nhau. Đây là nơi các Compare-Object cmdlet có ích:

Compare-Object $firstFolder $secondFolder -SyncWindow 0 

này sẽ trả về một mảng sự khác biệt giữa hai mảng hoặc $null khi các mảng đều bình đẳng. Chính xác hơn, mảng kết quả sẽ chứa một đối tượng cho mỗi mục chỉ tồn tại trong một mảng chứ không phải một mảng khác. Đối số -SyncWindow 0 sẽ thực hiện thứ tự các mục xuất hiện trong các mảng được tính là khác biệt.

Nếu tất cả bạn cần là một cách đơn giản để nói cho dù hai mảng khác nhau mà không đi vào chi tiết của là khác nhau, bạn chỉ có thể kiểm tra độ dài của mảng trả về bởi Compare-Object:

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

Lưu ý cách tôi đã nói rõ ràng với PowerShell để luôn luôn đóng gói các kết quả vào một mảng, vì Compare-Object có thể trả lại $null khi các mảng không chứa bất kỳ sự khác biệt nào.

+0

Cảm ơn bạn, Enrico. Ý bạn là, nó so sánh tên của các mảng thay vì nội dung của chúng? – culter

+0

@culter Toán tử '-eq' thực sự so sánh đối tượng đầu tiên trong mỗi mảng. Xem câu trả lời cập nhật của tôi. –

+0

Cảm ơn bạn đã trả lời hết sức, Enrico. Nó hoạt động hoàn hảo. Nhưng như bạn đã viết, toán tử -eq so sánh đối tượng đầu tiên của mỗi mảng, tại sao nó trả về false khi tôi so sánh cùng một thư mục? – culter

4

Đối với loại so sánh này, bạn phải sử dụng lệnh ghép ngắn compare-object và đánh giá xem có sự khác biệt hay không!