Compare-Object

比较两组对象。

语法

Compare-Object
       [-ReferenceObject] <PSObject[]>
       [-DifferenceObject] <PSObject[]>
       [-SyncWindow <Int32>]
       [-Property <Object[]>]
       [-ExcludeDifferent]
       [-IncludeEqual]
       [-PassThru]
       [-Culture <String>]
       [-CaseSensitive]
       [<CommonParameters>]

说明

Compare-Object cmdlet 比较两组对象。 一组对象是 引用,另一组对象是 差异

Compare-Object 检查比较整个对象的可用方法。 如果找不到合适的方法,它将调用输入对象的 ToString() 方法,并比较字符串结果。 可以提供一个或多个要用于比较的属性。 提供属性时,cmdlet 仅比较这些属性的值。

比较的结果指示属性值仅出现在 引用 对象(<=)中,还是仅出现在 差异 对象(=>)。 如果使用了 IncludeEqual 参数,则 (==) 指示值在这两个对象中。

如果 引用差异 对象为 null($null),Compare-Object 将生成终止错误。

一些示例使用旋转来减少代码示例的行长度。 有关详细信息,请参阅 about_Splatting

示例

示例 1 - 比较两个文本文件的内容

此示例比较两个文本文件的内容。 该示例使用以下两个文本文件,每个文本文件位于一个单独的行上。

  • Testfile1.txt 包含值:狗、松鼠和鸟。
  • Testfile2.txt 包含值:猫、鸟和龙。

输出仅显示文件之间的不同行。 Testfile1.txt引用 对象(<=),Testfile2.txt对象(=>)的 差异。 不显示两个文件中显示的内容行。

Compare-Object -ReferenceObject (Get-Content -Path C:\Test\Testfile1.txt) -DifferenceObject (Get-Content -Path C:\Test\Testfile2.txt)

InputObject SideIndicator
----------- -------------
cat         =>
racoon      =>
dog         <=
squirrel    <=

示例 2 - 比较每行内容并排除差异

此示例使用 ExcludeDifferent 参数比较两个文本文件中每行内容。

从 PowerShell 7.1 起,使用 ExcludeDifferent 参数时,将推断 IncludeEqual,并且输出仅包含这两个文件中包含的行,如 SideIndicator==所示)。

$objects = @{
  ReferenceObject = (Get-Content -Path C:\Test\Testfile1.txt)
  DifferenceObject = (Get-Content -Path C:\Test\Testfile2.txt)
}
Compare-Object @objects -ExcludeDifferent

InputObject SideIndicator
----------- -------------
bird        ==

示例 3 - 显示使用 PassThru 参数时的差异

通常,Compare-Object 返回具有以下属性的 PSCustomObject 类型:

  • 正在比较 InputObject
  • SideIndicator 属性,显示输出所属的输入对象

使用 PassThru 参数时,对象的 类型 不会更改,但返回的对象实例已添加 NotePropertySideIndicatorSideIndicator 显示输出所属的输入对象。

以下示例显示了不同的输出类型。

$a = $True
Compare-Object -IncludeEqual $a $a
(Compare-Object -IncludeEqual $a $a) | Get-Member

InputObject SideIndicator
----------- -------------
       True ==

   TypeName: System.Management.Automation.PSCustomObject
Name          MemberType   Definition
----          ----------   ----------
Equals        Method       bool Equals(System.Object obj)
GetHashCode   Method       int GetHashCode()
GetType       Method       type GetType()
ToString      Method       string ToString()
InputObject   NoteProperty System.Boolean InputObject=True
SideIndicator NoteProperty string SideIndicator===

Compare-Object -IncludeEqual $a $a -PassThru
(Compare-Object -IncludeEqual $a $a -PassThru) | Get-Member

True

   TypeName: System.Boolean
Name          MemberType   Definition
----          ----------   ----------
CompareTo     Method       int CompareTo(System.Object obj), int CompareTo(bool value), int IComparable.CompareTo(Syst
Equals        Method       bool Equals(System.Object obj), bool Equals(bool obj), bool IEquatable[bool].Equals(bool ot
GetHashCode   Method       int GetHashCode()
GetType       Method       type GetType()
GetTypeCode   Method       System.TypeCode GetTypeCode(), System.TypeCode IConvertible.GetTypeCode()
ToBoolean     Method       bool IConvertible.ToBoolean(System.IFormatProvider provider)
ToByte        Method       byte IConvertible.ToByte(System.IFormatProvider provider)
ToChar        Method       char IConvertible.ToChar(System.IFormatProvider provider)
ToDateTime    Method       datetime IConvertible.ToDateTime(System.IFormatProvider provider)
ToDecimal     Method       decimal IConvertible.ToDecimal(System.IFormatProvider provider)
ToDouble      Method       double IConvertible.ToDouble(System.IFormatProvider provider)
ToInt16       Method       short IConvertible.ToInt16(System.IFormatProvider provider)
ToInt32       Method       int IConvertible.ToInt32(System.IFormatProvider provider)
ToInt64       Method       long IConvertible.ToInt64(System.IFormatProvider provider)
ToSByte       Method       sbyte IConvertible.ToSByte(System.IFormatProvider provider)
ToSingle      Method       float IConvertible.ToSingle(System.IFormatProvider provider)
ToString      Method       string ToString(), string ToString(System.IFormatProvider provider), string IConvertible.To
ToType        Method       System.Object IConvertible.ToType(type conversionType, System.IFormatProvider provider)
ToUInt16      Method       ushort IConvertible.ToUInt16(System.IFormatProvider provider)
ToUInt32      Method       uint IConvertible.ToUInt32(System.IFormatProvider provider)
ToUInt64      Method       ulong IConvertible.ToUInt64(System.IFormatProvider provider)
TryFormat     Method       bool TryFormat(System.Span[char] destination, [ref] int charsWritten)
SideIndicator NoteProperty string SideIndicator===

使用 PassThru时,将返回原始对象类型(System.Boolean)。 请注意,System.Boolean 对象的默认格式显示的输出如何未显示 SideIndicator 属性。 但是,返回的 System.Boolean 对象已添加 NoteProperty

示例 4 - 使用属性比较两个简单对象

在此示例中,我们将比较两个长度相同的不同字符串。

Compare-Object -ReferenceObject 'abc' -DifferenceObject 'xyz' -Property Length -IncludeEqual

Length SideIndicator
------ -------------
     3 ==

示例 5 - 使用属性比较复杂对象

此示例显示比较复杂对象时的行为。 在此示例中,我们为 PowerShell 的不同实例存储两个不同的进程对象。 这两个变量都包含具有相同名称的进程对象。 如果未指定 属性 参数,则 cmdlet 会将对象视为相等。 请注意,InputObject 的值与 ToString() 方法的结果相同。 由于 System.Diagnostics.Process 类没有 IComparable 接口,因此 cmdlet 会将对象转换为字符串,然后比较结果。

PS> Get-Process pwsh

 NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
    101   123.32     139.10      35.81   11168   1 pwsh
     89   107.55      66.97      11.44   17600   1 pwsh

PS> $a = Get-Process -Id 11168
PS> $b = Get-Process -Id 17600
PS> $a.ToString()
System.Diagnostics.Process (pwsh)
PS> $b.ToString()
System.Diagnostics.Process (pwsh)
PS> Compare-Object $a $b -IncludeEqual

InputObject                       SideIndicator
-----------                       -------------
System.Diagnostics.Process (pwsh) ==

PS> Compare-Object $a $b -Property ProcessName, Id, CPU

ProcessName    Id       CPU SideIndicator
-----------    --       --- -------------
pwsh        17600   11.4375 =>
pwsh        11168 36.203125 <=

指定要比较的属性时,cmdlet 会显示差异。

示例 6 - 比较实现 IComparable 的复杂对象

如果对象实现 IComparable,则 cmdlet 将搜索比较对象的方法。如果对象类型不同,则 Difference 对象将转换为 ReferenceObject 的类型,然后进行比较。

在此示例中,我们将字符串与 TimeSpan 对象进行比较。 在第一种情况下,字符串将转换为 TimeSpan 以便对象相等。

Compare-Object ([TimeSpan]"0:0:1") "0:0:1" -IncludeEqual

InputObject SideIndicator
----------- -------------
00:00:01    ==

Compare-Object "0:0:1" ([TimeSpan]"0:0:1")

InputObject SideIndicator
----------- -------------
00:00:01    =>
0:0:1       <=

第二种情况下,TimeSpan 转换为字符串,以便对象不同。

参数

-CaseSensitive

指示比较应区分大小写。

类型:SwitchParameter
Position:Named
默认值:False
必需:False
接受管道输入:False
接受通配符:False

-Culture

指定要用于比较的区域性。

类型:String
Position:Named
默认值:None
必需:False
接受管道输入:False
接受通配符:False

-DifferenceObject

指定与 引用 对象进行比较的对象。

类型:PSObject[]
Position:1
默认值:None
必需:True
接受管道输入:True
接受通配符:False

-ExcludeDifferent

指示此 cmdlet 仅显示相等的比较对象的特征。 放弃对象之间的差异。

ExcludeDifferentIncludeEqual 配合使用,仅显示 引用差异 对象之间的匹配行。

如果未 IncludeEqual指定 ExcludeDifferent,则没有输出。

类型:SwitchParameter
Position:Named
默认值:False
必需:False
接受管道输入:False
接受通配符:False

-IncludeEqual

IncludeEqual 显示 引用差异 对象之间的匹配项。

默认情况下,输出还包括 引用差异 对象之间的差异。

类型:SwitchParameter
Position:Named
默认值:False
必需:False
接受管道输入:False
接受通配符:False

-PassThru

使用 PassThru 参数时,Compare-Object 省略比较对象周围的 PSCustomObject 包装器,并返回不同对象不变。

类型:SwitchParameter
Position:Named
默认值:False
必需:False
接受管道输入:False
接受通配符:False

-Property

指定要比较的 引用差异 对象的属性数组。

属性 参数的值可以是新的计算属性。 计算属性可以是脚本块或哈希表。 有效的键值对包括:

  • 表达式 - <string><script block>

有关详细信息,请参阅 about_Calculated_Properties

类型:Object[]
Position:Named
默认值:None
必需:False
接受管道输入:False
接受通配符:False

-ReferenceObject

指定用作比较引用的对象数组。

类型:PSObject[]
Position:0
默认值:None
必需:True
接受管道输入:False
接受通配符:False

-SyncWindow

指定在查找对象集合中的匹配项时 Compare-Object 检查的相邻对象的数量。 Compare-Object 在集合中找不到位于相同位置的对象时检查相邻对象。 默认值为 [Int32]::MaxValue,这意味着 Compare-Object 检查整个对象集合。

使用大型集合时,默认值可能效率不高,但准确。 为 SyncWindow 指定较小的值可以提高性能,但准确性可能较低。

类型:Int32
Position:Named
默认值:[Int32]::MaxValue
必需:False
接受管道输入:False
接受通配符:False

输入

PSObject

可以将对象向下发送到 DifferenceObject 参数。

输出

None

默认情况下,当 ReferenceObjectDifferenceObject 相同时,此 cmdlet 不返回任何输出。

PSCustomObject

当对象不同时,此 cmdlet 使用 SideIndicator 属性将不同对象包装在 PSCustomObject 包装器中以引用差异。

使用 IncludeEqual 参数和对象相同时,cmdlet 将返回 PSCustomObject 中包装的对象,SideIndicator 属性设置为 ==

使用 PassThru 参数时,对象的 类型 不会更改,但返回的对象实例已添加 NotePropertySideIndicatorSideIndicator 显示输出所属的输入对象。

备注

PowerShell 包含以下 Compare-Object别名:

  • 窗户:
    • compare
    • diff

使用 PassThru 参数时,控制台中显示的输出可能不包含 SideIndicator 属性。 Compare-Object 的对象类型输出的默认格式视图不包括 SideIndicator 属性。 有关详细信息,请参阅本文中的 示例 3