当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] PowerShell 比较对象:综合指南

作者:精品下载站 日期:2024-12-14 21:39:23 浏览:12 分类:玩电脑

PowerShell 比较对象:综合指南


比较数据集并识别差异是编程和脚本编写中的常见任务。在 PowerShell 中处理对象和值时,您经常需要找出两组数据之间发生了什么变化。这就是强大的 Compare-Object cmdlet 的用武之地。Compare-Object cmdlet 提供了一种快速、简单的方法来比较两组对象并揭示差异。在本深入指南中,我将带您了解有关掌握 PowerShell 的 Compare-Object 以进行高效数据分析所需了解的所有信息。

在这篇文章中,我将提供有关在 PowerShell 中使用 Compare-Object 的全面指南。我们将介绍:

  • Compare-Object 的用途以及何时使用它
  • 比较两组对象/数据并输出差异
  • 使用 Compare-Object 查找两个对象之间的匹配项
  • 基于特定对象属性而不是完整对象进行比较
  • 比较文件、CSV 等中的数据
  • 过滤和格式化报告的比较对象输出

您将学习利用 Compare-Object 有效比较 PowerShell 对象并揭示有意义的差异的最佳实践。无论您是比较系统设置、文件夹、审核更改还是分析数据集,这篇文章都将帮助您掌握 Compare-Object。最后,您将能够利用 Compare-Object 的强大功能来隔离 PowerShell 脚本和工作流程中的对象之间的重要更改。准备好开始比较了吗?我们走吧!

PowerShell 比较对象简介

PowerShell 的 Compare-Object 是一个 cmdlet,可让您比较两组数据并识别它们之间的差异。当您使用数组、列表或对象数组时,这尤其有用。通过使用Compare-Object,您可以轻松找到两组数据之间缺失、添加或更改的项目。

了解 Compare-Object 的语法和参数

在我们深入使用 Compare-Object 之前,了解它的语法和参数很重要。 Compare-Object的基本语法如下:


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

下面对每个参数进行简单解释:

-ReferenceObject

指定引用对象的数组。这是您要比较的主要对象集。通常,这是“已知”或“标准”数据集。

-DifferenceObject

指定要与参考对象进行比较的对象数组。通常,这是“新”或“变量”数据集。

-Property

指定要比较的属性。如果未指定此参数,cmdlet 将比较对象本身。

-CaseSensitive

使比较区分大小写。默认情况下,比较不区分大小写。

-Culture

指定比较中使用的区域性。这对于字符串比较很重要,因为不同文化中的字符可能会受到不同的处理。

-ExcludeDifferent

从输出对象中排除不同的对象。它仅显示相同的对象。

-IncludeEqual

显示相等的对象。默认情况下,仅显示差异。

-PassThru

通过管道传递输出对象。

-SyncWindow

指定要在比较中包含的不同对象周围的相邻对象数。当比较可能稍微乱序但仍被视为匹配的对象时,此参数非常重要。

使用 Compare-Object 比较数组

使用 Compare-Object 最常见的方法之一是比较两个数组。数组是按特定顺序存储的项目的集合。 PowerShell 的 Compare-Object 可以比较两个数组并识别丢失、添加或更改的项目。

要使用 Compare-Object 比较两个数组,您需要将数组指定为 ReferenceObject 和 DifferenceObject 参数。为了掌握基础知识,让我们从一个基本的比较对象 PowerShell 示例开始:


$Array1 = @(1, 2, 3, 4, 5)
$Array2 = @(1, 2, 4, 5, 6)

Compare-Object -ReferenceObject $Array1 -DifferenceObject $Array2

上面的代码将比较两个数组并返回差异。这是一个简单的用例,展示了 PowerShell 比较功能的能力。这是输出:


InputObject SideIndicator
----------- -------------
6           =>
3           <=

在此示例中,SideIndicator 列指示数字 3 在 ReferenceObject 数组中(由 符号指示)并且不在 ReferenceObject 数组中。

Compare-Object 将第一组中的对象与第二组中的对象进行检查,以确定:

  • 仅在集合 1 中的对象(添加)
  • 仅第 2 组中的物体(移除)
  • 两者都有对象,但具有不同的属性(更改)

这样可以轻松查看任意两个对象集合之间添加、删除或修改的内容。

比较数组是一项常见任务,尤其是当您想要找出哪些元素存在于一个数组中但不存在于另一个数组中时。考虑下面的例子:


$FirstArray = "apple", "banana", "cherry"
$SecondArray = "banana", "cherry", "date"

#Compare Arrays
Compare-Object $FirstArray $SecondArray

在此 PowerShell 比较两个数组的示例中,第一个数组中的“apple”和第二个数组中的“date”将作为差异返回。


InputObject SideIndicator
----------- -------------
date        =>           
apple       <=           

我们可以创建一个函数来比较给定的数组并返回比较结果。


Function Check-ObjectsEqual {
    param (
        [Parameter(Mandatory=$true)]
        $Object1,

        [Parameter(Mandatory=$true)]
        $Object2
    )

    $ComparisonResult = Compare-Object -ReferenceObject $Object1 -DifferenceObject $Object2

    # If there are no differences, return $true, otherwise return $false
    return ($null -eq $comparisonResult)
}

# Example Usage:

$Array1 = 1,2,3,4,5
$Array2 = 1,2,3,4,5,6

if (Check-ObjectsEqual -Object1 $Array1 -Object2 $Array2) {
    Write-Output "The objects are equal."
} else {
    Write-Output "The objects are not equal."
}

如果您想比较给定的对象,请使用以下命令而不是数组:


Function Check-Objects {
    param(
        [Parameter(Mandatory = $true)]
        $Object1,
        [Parameter(Mandatory = $false)]
        $Object2
    )

    return !(Compare-Object $Object1.PSObject.Properties $Object2.PSObject.Properties)
}

$PSCustomObj1 = [PSCustomObject]@{
    Name = "John"
    Age = 20
    City = "Anytown"
}

$PSCustomObj2 = [PSCustomObject]@{
    Name = "John"
    Age = 30
    City = "Anytown"
}

Check-Objects $PSCustomObj1 $PSCustomObj2

比较并仅返回匹配的项目

让我们看一下比较两组对象的示例。仅返回匹配项:


#Get Server Names from text files
$Servers1 = Get-Content C:\Data\Servers1.txt
$Servers2 = Get-Content C:\Data\Servers2.txt

#Compare two object arrays and list the uniform elements
Compare-Object $Servers1 $Servers2 -IncludeEqual -ExcludeDifferent | Select -ExpandProperty InputObject

这将打印两组中匹配的对象,排除差异。

使用 Compare-Object 比较列表

使用 Compare-Object 的另一种常见方法是比较两个列表。列表与数组类似,但它不按特定顺序存储。 PowerShell 的 Compare-Object 可以比较两个列表并识别丢失、添加或更改的项目。

就像数组一样,您可以比较两个列表:


# Create Lists
$EUServers = [System.Collections.Generic.List[string]]("EUS-WEB-01", "APP-TOK-01", "EUS-API-03")
$USServers = [System.Collections.Generic.List[string]]("ES-MAD-003", "APP-TOK-01", "US-CHI-001")

# Compare Lists
Compare-Object $EUServers $USServers

要使用 Compare-Object 比较两个列表,您需要将列表指定为 ReferenceObject 和 DifferenceObject 参数。这是另一个例子:


$List1 = 1, 2, 3, 4, 5
$List2 = 1, 2, 4, 5, 6

Compare-Object $List1 $List2

这将返回以下输出:


InputObject SideIndicator
----------- -------------
3           <=           
6           =>      

如您所见,输出与比较数组时的输出相同。

使用 Compare-Object 比较对象数组

对象数组是一个数组,其中每个项目都是一个具有属性的对象。 PowerShell 的 Compare-Object 可以比较两个对象数组并识别丢失、添加或更改的对象。

要使用 Compare-Object 比较两个对象数组,您需要将数组指定为 ReferenceObject 和 DifferenceObject 参数。您还需要使用 Property 参数指定将用于比较的属性。这是一个例子:


$ObjectArray1 = @( 
    [pscustomobject] @{ Name = 'John'; Age = 30 },
    [pscustomobject] @{ Name = 'Jane'; Age = 25 },
    [pscustomobject] @{ Name = 'Bob'; Age = 40 }
)

$ObjectArray2 = @( 
    [pscustomobject] @{ Name = 'John'; Age = 30 },
    [pscustomobject] @{ Name = 'Jane'; Age = 26 },
    [pscustomobject] @{ Name = 'Alice'; Age = 35 }
)

Compare-Object $ObjectArray1 $ObjectArray2 -Property Name, Age

在这里,在 PowerShell 比较对象数组示例中,我们正在比较两个具有多个属性的自定义对象。这将返回以下输出:


Name Age SideIndicator
---- --- -------------
Jane   25   <=           
Jane   26   =>           
Bob    40   <=           
Alice  35   =>

在此示例中,我们根据 Name 和 Age 属性比较两个对象数组。 SideIndicator 列指示名称为 Jane、年龄为 25 的对象位于 ReferenceObject 数组中而不是在 DifferenceObject 数组中,名称为 Jane 且年龄为 26 的对象位于 DifferenceObject 数组中而不是在 ReferenceObject 数组中,依此类推。

请注意,当您比较对象时,您必须使用“Property”参数。因为 Compare-Object 只是比较对象属性的字符串表示形式。

这是一个比较机器上进程的真实示例:假设您正在尝试比较同一台机器上两个不同时间点之间的进程。


# Step 1: Capture processes at T1
$T1Processes = Get-Process | Select-Object -ExpandProperty ProcessName

#Start Notepad
Start-Process Notepad

# Step 2: Capture processes at T2 (let's assume a new process "notepad" has started by now)
$T2Processes = Get-Process | Select-Object -ExpandProperty ProcessName

# Step 3: Compare the two lists
$ComparisonResult = Compare-Object -ReferenceObject $T1Processes -DifferenceObject $T2Processes

# Display the differences
$ComparisonResult

比较目录内容

Compare-Object 的优点之一是它适用于多种对象类型。比较目录内容:


Compare-Object (Get-ChildItem C:\Source) (Get-ChildItem C:\Destination)

这揭示了目录中文件和文件夹之间的差异。您可以使用以下方法比较两个库中的所有文件:


$SourceFiles = Get-ChildItem -Path "C:\Source" -Recurse
$DestinationFiles = Get-ChildItem -Path "C:\Destination" -Recurse
Compare-Object $SourceFiles $DestinationFiles -Property Name, Length

使用 Compare-Object 比较多个属性

有时,您可能需要根据多个属性比较两组数据。 PowerShell 的 Compare-Object 允许您通过使用 Property 参数指定多个属性来实现此目的。

这是一个例子:


$ObjectArray1 = @( 
    [pscustomobject] @{ Name = 'John'; Age = 30; City = 'New York' },
    [pscustomobject] @{ Name = 'Jane'; Age = 25; City = 'Los Angeles' },
    [pscustomobject] @{ Name = 'Bob'; Age = 40; City = 'Chicago' }
)

$ObjectArray2 = @( 
    [pscustomobject] @{ Name = 'John'; Age = 30; City = 'New York' },
    [pscustomobject] @{ Name = 'Jane'; Age = 26; City = 'Los Angeles' },
    [pscustomobject] @{ Name = 'Alice'; Age = 35; City = 'Chicago' }
)

Compare-Object $ObjectArray1 $ObjectArray2 -Property Name, Age, City

这将返回以下输出:


Name  Age City        SideIndicator
----  --- ----        -------------
Jane   26 Los Angeles =>           
Alice  35 Chicago     =>           
Jane   25 Los Angeles <=           
Bob    40 Chicago     <=           

在此示例中,我们根据“名称”、“年龄”和“城市”属性比较两个对象数组。 SideIndicator 列指示名称为 Jane、年龄 25 和城市洛杉矶的对象位于 ReferenceObject 数组中,而不是在 DifferenceObject 数组中,名称为 Jane、年龄 26 和城市洛杉矶的对象位于 DifferenceObject 数组中并且不在 ReferenceObject 数组中,等等。

在比较对象中使用 SideIndicator 参数

Compare-Object 中的 SideIndicator 参数是一个功能强大的工具,可让您过滤掉与分析无关的项目。 SideIndicator 列指示某个项目是否位于 ReferenceObject 数组、DifferenceObject 数组或两者中。

当您从 Compare-Object 获得结果时,您将看到 SideIndicator 属性。他们的意思是这样的:

  • =>:该对象存在于 DifferenceObject(或第二个输入)中。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯