使用格式设置和筛选
使用 PowerShell 时,出于几个原因,“筛选”和“格式设置”是要了解的重要概念。 首先,你需要创建一个可生成所需结果的管道。 其次,你希望在以下方面能高效地实现这一点: 如何通过网络拉出数据和如何确保结果是你可以使用的结果。
筛选左侧
在管道语句中,筛选左侧意味着尽可能早地筛选所需的结果。 由于 PowerShell 语句从左往右运行,因此,可以将“左侧”一词视为“尽早”。 此筛选思路是,通过确保所操作的数据集尽可能小,使语句更快更高效。 当你的命令在较大的数据存储上运行时,或者当你通过网络返回结果时,此原则就会发挥作用。
请考虑下列语句:
Get-Process | Select-Object Name | Where-Object Name -eq 'name-of-process'
此语句首先检索计算机上的所有进程。 它最终需要设置响应的格式,以便只列出 Name
属性。 此语句不遵循筛选左侧原则,因为它对所有进程进行操作,尝试格式化响应,然后在结束时进行筛选。
最好首先筛选,然后再进行格式化,如以下语句中所示。
Get-Process | Where-Object Name -eq 'name-of-process' | Select-Object Name
通常,提供筛选的 cmdlet 比使用 Where-Object
更为有效。 下面是上述语句的更有效版本:
Get-Process -Name 'name-of-process' | Select-Object Name
在此版本中,参数 -Name
执行筛选操作。
正确设置格式,将格式设置作为最后一项操作
鉴于筛选左侧在语句中是指尽可能早地筛选出内容,从右往左格式化数据在语句中就是指尽可能晚地格式化数据。 但为什么需要延迟设置格式? 这是因为格式命令会更改包含结果的对象的结构,因此相同属性中找不到你的数据。 此更改会影响你使用管道命令 Select-Object
或使用 foreach
循环访问结果来检索所需信息的能力。
格式设置会破坏你正在处理的对象。 以下面的调用为例:
Get-Process 'some process' | Select-Object Name, CPU | Get-Member
返回的类型为 System.Diagnostics.Process
。 现在,添加格式化程序 Format-Table
,如下所示:
Get-Process 'some process' | Format-Table Name,CPU | Get-Member
只关注返回的类型时,可以注意到返回的内容不同:
TypeName: Microsoft.PowerShell.Commands.Internal.Format.FormatStartData
TypeName: Microsoft.PowerShell.Commands.Internal.Format.GroupStartData
TypeName: Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData
TypeName: Microsoft.PowerShell.Commands.Internal.Format.GroupEndData
这些类型是什么对于本课程来说并不重要。 需要注意的是,使用任何类型的格式设置命令时,数据都是不同的。 当数据不同时,它可能不再包含你关注的列。 我们将用一个示例加以说明:
Get-Process 'some process' | Select-Object Name, Cpu
上述命令会提供具有列 Name
和 CPU
的结果。
Name CPU
---- ---
zsh 1.2984395
zsh 0.2522047
zsh 0.2486375
zsh 0.2683466
zsh 0.2681874
zsh 1.6799438
zsh 0.2909816
zsh 0.7855272
我们先使用格式设置,然后使用 Select-Object
来说明如果最后不设置格式会发生什么:
Get-Process 'some process' | Format-Table Name,CPU | Select-Object Name, CPU
结果现在如下所示:
Name CPU
---- ---
它是空值,因为 Format-Table
通过将数据置于其他属性中转换了包含结果的对象。 数据没有消失,只有属性会消失。 前面的 PowerShell 命令尝试查找属性,但无法找到。
格式设置命令应该是你在语句中最不常用的命令,因为它们用于针对屏幕演示美观地设置格式。 它们不用于对数据进行筛选或排序。
格式设置命令
用于格式化输出的最常见 cmdlet 是 Format-Table
和 Format-List
。 默认情况下,大多数 cmdlet 都会将输出格式化为表。 如果不希望输出以列显示属性,请使用 Format-List
cmdlet 将它们重新格式化为列表。