使用 Compare-Object 比較兩個陣列
PS C:\> $arr1 = 'A', 'B', 'C'
PS C:\> $arr2 = 'A', 'B', 'D'
PS C:\> compare $arr1 $arr2
InputObject SideIndicator
----------- -------------
D =>
C <=
PS C:\> $arr1 = 'A', 'B', 'C'
PS C:\> $arr2 = 'A', 'B', 'D'
PS C:\> compare $arr1 $arr2 -IncludeEqual
InputObject SideIndicator
----------- -------------
A ==
B ==
D =>
C <=
== 已配對
<= 左邊沒有配對的
=> 右邊沒有配對的
PS C:\> $arr1 = 'A', 'B', 'C'
PS C:\> $arr2 = 'A', 'B', 'B'
PS C:\> compare $arr1 $arr2 -IncludeEqual
InputObject SideIndicator
----------- -------------
A ==
B ==
B =>
C <=
$arr2 有兩個B
其中一個已配對,另一個沒有配對
可以是 1個物件
or 1個陣列
(空陣列也可以)
不可以是 $null
PS C:\> $arr1 = 'A', 'B', 'C'
PS C:\> compare $arr1 'P'
InputObject SideIndicator
----------- -------------
P =>
A <=
B <=
C <=
PS C:\> $arr1 = 'A', 'B', 'C'
PS C:\> compare $arr1 @()
InputObject SideIndicator
----------- -------------
A <=
B <=
C <=
報錯
PS C:\> $arr1 = 'A', 'B', 'C'
PS C:\> compare $arr1 $null
Compare-Object : 無法將引數繫結到 'DifferenceObject' 參數,因為它是 Null。
位於 線路:1 字元:15
+ compare $arr1 $null
+ ~~~~~
# $arr1 可能是 $null
$arr1 = dir *.txt
# $arr1 是一個陣列 (內含 0個物件 or 1個物件 or 多個物件)
$arr1 = @(dir *.txt)
物件本身
進行比較右邊的物件會`轉型`成左邊的型別,然後進行比較
PS C:\> compare ([TimeSpan]"0:0:1") "0:0:1" -IncludeEqual
InputObject SideIndicator
----------- -------------
00:00:01 ==
左邊右邊換位置
PS C:\> compare "0:0:1" ([TimeSpan]"0:0:1") -IncludeEqual
InputObject SideIndicator
----------- -------------
00:00:01 =>
0:0:1 <=
PS C:\001> compare @(dir) @(dir) -IncludeEqual
InputObject SideIndicator
----------- -------------
1.txt ==
A.txt ==
B.txt ==
PS C:\001> compare @(dir) @(dir *) -IncludeEqual
InputObject SideIndicator
----------- -------------
C:\001\1.txt =>
C:\001\A.txt =>
C:\001\B.txt =>
1.txt <=
A.txt <=
B.txt <=
物件的屬性
進行比較 (使用 -Property 參數)PS C:\001> compare @(dir) @(dir *) -IncludeEqual -Property Name
Name SideIndicator
---- -------------
1.txt ==
A.txt ==
B.txt ==
2個屬性
PS C:\001> compare @(dir) @(dir *) -IncludeEqual -Property Name, Length
Name Length SideIndicator
---- ------ -------------
1.txt 4229 ==
A.txt 10538 ==
B.txt 10630 ==
3個屬性
PS C:\001> compare @(dir) @(dir *) -IncludeEqual -Property Name, Length, LastWriteTime
Name Length LastWriteTime SideIndicator
---- ------ ------------- -------------
1.txt 4229 2023/8/20 下午 12:16:20 ==
A.txt 10538 2023/8/20 下午 12:16:20 ==
B.txt 10630 2023/8/20 下午 12:16:20 ==
屬性名:不可以用 *
PS C:\001> compare @(dir) @(dir *) -IncludeEqual -Property *
compare : "*" 中不允許有萬用字元。
script block
PS C:\001> $e = { (Get-FileHash $_ -algo MD5).Hash }
PS C:\001> compare @(dir) @(dir *) -IncludeEqual -Property Name, Length, $e
Name Length (Get-FileHash $_ -algo MD5).Hash SideIndicator
---- ------ ---------------------------------- -------------
1.txt 4229 43D7571729083C00CDD4737312728924 ==
A.txt 10538 3C5F75F757513FDFBC2BEED2846694DF ==
B.txt 10630 896EBC708B542A54ADECC2C850FBD43C ==
hash table
PS C:\001> $e = { (Get-FileHash $_ -algo MD5).Hash }
PS C:\001> compare @(dir) @(dir *) -IncludeEqual -Property Name, Length, @{ e = $e }
Name Length (Get-FileHash $_ -algo MD5).Hash SideIndicator
---- ------ ---------------------------------- -------------
1.txt 4229 43D7571729083C00CDD4737312728924 ==
A.txt 10538 3C5F75F757513FDFBC2BEED2846694DF ==
B.txt 10630 896EBC708B542A54ADECC2C850FBD43C ==
只列出沒有配對
PS C:\> $arr1 = 'A', 'B', 'C'
PS C:\> $arr2 = 'A', 'B', 'D'
PS C:\> compare $arr1 $arr2
InputObject SideIndicator
----------- -------------
D =>
C <=
功能:列出已配對
結果:沒有配對
、已配對
PS C:\> $arr1 = 'A', 'B', 'C'
PS C:\> $arr2 = 'A', 'B', 'D'
PS C:\> compare $arr1 $arr2 -IncludeEqual
InputObject SideIndicator
----------- -------------
A ==
B ==
D =>
C <=
功能:不列出沒有配對
PowerShell 5 的結果:沒反應
PS C:\> $arr1 = 'A', 'B', 'C'
PS C:\> $arr2 = 'A', 'B', 'D'
PS C:\> compare $arr1 $arr2 -ExcludeDifferent
PS C:\>
PowerShell 7 的結果:已配對
PS C:\> $arr1 = 'A', 'B', 'C'
PS C:\> $arr2 = 'A', 'B', 'D'
PS C:\> compare $arr1 $arr2 -ExcludeDifferent
InputObject SideIndicator
----------- -------------
A ==
B ==
功能:不列出沒有配對
、列出已配對
結果:已配對
PS C:\> $arr1 = 'A', 'B', 'C'
PS C:\> $arr2 = 'A', 'B', 'D'
PS C:\> compare $arr1 $arr2 -ExcludeDifferent -IncludeEqual
InputObject SideIndicator
----------- -------------
A ==
B ==
結果物件的型別:來源物件
PS C:\> compare (dir C:\001) (dir C:\002) -PassThru
目錄: C:\002
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2023/8/20 下午 12:16 3770 2.txt
目錄: C:\001
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2023/8/20 下午 12:16 4229 1.txt
結果物件的型別:PSCustomObject
PS C:\> compare (dir C:\001) (dir C:\002)
InputObject SideIndicator
----------- -------------
2.txt =>
1.txt <=
來源物件
、PSCustomObject
的共同點它們都有SideIndicator屬性,可以得知
<=
==
=>
來源物件:只傳回左邊
的來源物件
PSCustomObject:InputObject屬性是左邊
的來源物件
InputObject屬性的由來:沒有使用 -property 參數,以物件本身
進行比較
使用Count屬性
PS C:\> $r = compare 'A' 'A'
PS C:\> $null -eq $r
True
PS C:\> $r.count
0
Count屬性沒反應
PS C:\> $r = compare 'A' 'A' -IncludeEqual
PS C:\> $r.gettype().name
PSCustomObject
PS C:\> $r.count
PS C:\>
把結果放進 @( ) 裡面,使它成為一個陣列
然後使用Count屬性
PS C:\> $r = compare 'A' 'A'
PS C:\> $null -eq $r
True
PS C:\> @($r).count
0
PS C:\> $r = compare 'A' 'A' -IncludeEqual
PS C:\> $r.gettype().name
PSCustomObject
PS C:\> @($r).count
1
SideIndicator屬性
選取結果PS C:\> $arr1 = 'A', 'B', 'C'
PS C:\> $arr2 = 'A', 'B', 'D'
PS C:\> $r = compare $arr1 $arr2 -IncludeEqual
PS C:\> $r | where SideIndicator -eq '<='
InputObject SideIndicator
----------- -------------
C <=
PS C:\> $r | where SideIndicator -eq '=='
InputObject SideIndicator
----------- -------------
A ==
B ==
PS C:\> $r | where SideIndicator -eq '=>'
InputObject SideIndicator
----------- -------------
D =>
SyncWindow:暫存區的大小。預設值為[Int32]::MaxValue
左邊、右邊各有一個暫存區。
首先,同位置配對
當配對失敗
右邊物件:和左邊暫存區裡的物件配對
左邊物件:和右邊暫存區裡的物件配對
如果成功配對,把成功配對物件從暫存區中移除
如果沒有成功配對,把未配對的物件存到暫存區
如果暫存區滿了,先把最舊的物件取出、設定SideIndicator屬性
再把新的未配對物件,放進暫存區
當比對結束,把暫存區的物件取出,設定SideIndicator屬性
PS C:\> $arr1 = 'A', 'B', 'C'
PS C:\> $arr2 = 'C', 'B', 'A'
PS C:\> compare $arr1 $arr2 -IncludeEqual
InputObject SideIndicator
----------- -------------
B ==
A ==
C ==
-SyncWindow 0
同位置配對
配對失敗,不保存到暫存區
立刻設定 SideIndicator值
PS C:\> $arr1 = 'A', 'B', 'C'
PS C:\> $arr2 = 'C', 'B', 'A'
PS C:\> compare $arr1 $arr2 -IncludeEqual -SyncWindow 0
InputObject SideIndicator
----------- -------------
C =>
A <=
B ==
A =>
C <=