问题描述
用label"重命名标题,我想过滤最后一个SpaceLeft".但是它不能正常工作.例如:
Renaming the headers with 'label' and I'd like to filter on that last one 'SpaceLeft'. It doesn't work correctly though. For example:
Get-WmiObject win32_logicaldisk -ComputerName sfuslt167 -Filter "drivetype=3" |
Format-Table -Property deviceID,
@{label='freespace(GB)';expression={$_.freespace / 1GB -as [int]}},
@{label='Size(GB)';expression={$_.size / 1GB -as [int]}},
@{label='SpaceLeft';expression={$_.freespace / $_.size * 100}} |
Where-Object {$_.SpaceLeft -lt 10}
结果:
deviceID freespace(GB) Size(GB) SpaceLeft
-------- ------------- -------- ---------
C: 130 237 54.8893461475826
这应该什么都没有返回,因为SpaceLeft"中的值大于 WHERE 语句中指定的 10,但它返回了结果.这是为什么??
This should come back with nothing as the value in 'SpaceLeft' is greater than 10 being specified in the WHERE statement, yet it comes back with results. Why is this??
推荐答案
Lee Dailey 提供了关键指针在评论中:
Lee Dailey has provided the crucial pointer in a comment:
要转换数据以进一步程序化处理,请使用
Select-Object
或其他数据转换方法,例如通过ForEach-Object
.
To transform data for further programmatic processing, use
Select-Object
or other data-transformation methods, such as viaForEach-Object
.
仅使用 Format-*
cmdlet 来格式化数据显示,作为它们的名字暗示.
Only ever use the Format-*
cmdlets to format data for display, as their name suggests.
- PowerShell 的重大进化飞跃是通过管道发送对象而不是文本,而
Format-*
cmdlet,例如格式表
也发出对象,这些对象不再代表数据,而是 - 它们没有其他用途.
- PowerShell's great evolutionary leap was to send objects rather than text through the pipeline, and while
Format-*
cmdlets such asFormat-Table
emit objects as well, these objects no longer represent data, but formatting instructions for PowerShell's output-formatting system - they serve no other purpose.
因此,只需将 Format-Table
替换为 Select-Object
即可解决您的问题:
Therefore, simply replacing Format-Table
with Select-Object
solves your problem:
Get-WmiObject win32_logicaldisk -ComputerName sfuslt167 -Filter "drivetype=3" |
Select-Object -Property deviceID,
@{label='freespace(GB)';expression={$_.freespace / 1GB -as [int]}},
@{label='Size(GB)';expression={$_.size / 1GB -as [int]}},
@{label='SpaceLeft';expression={$_.freespace / $_.size * 100}} |
Where-Object {$_.SpaceLeft -lt 10}
然而,这两个 cmdlet 的共同点是能够接受基于哈希表的计算属性(@{ label = '...'; expression = { ... } }
),就像你的问题一样.
What the two cmdlets do have in common, however, is the ability to accept hashtable-based calculated properties (@{ label = '...'; expression = { ... } }
), as in your question.
至于实际发生了什么:
这是一个简化的例子,使用Format-Table
:
Here's a simplified example, using Format-Table
:
PS> [pscustomobject] @{ freespace = 100; size = 1000 } |
Format-Table @{label='SpaceLeft'; expression={$_.freespace / $_.size * 100}}
SpaceLeft
---------
10
这看起来很好 - 事实上这就是目的 - 产生一个漂亮的显示表示.
This looks just fine - and indeed that's the purpose - producing a nice display representation.
事实上,用Select-Object
代替Format-Table
会得到相同的显示:
In fact, substituting Select-Object
for Format-Table
results in the same display:
PS> [pscustomobject] @{ freespace = 100; size = 1000 } |
Select-Object @{ label='SpaceLeft'; expression={$_.freespace / $_.size * 100} }
SpaceLeft
---------
10
原因是,当命令输出到显示时,PowerShell 隐式地,在幕后调用适当的Format-*
cmdlet,在本例中为 Format-Table
.换句话说,上面的命令等价于下面的命令:
The reason is that when command output goes to the display, PowerShell implicitly, behind the scenes calls an appropriate Format-*
cmdlet, which in this case is Format-Table
.In other words, the command above is equivalent to the following command:
PS> [pscustomobject] @{ freespace = 100; size = 1000 } |
Select-Object @{label='SpaceLeft'; expression={$_.freespace / $_.size * 100}} |
Format-Table
SpaceLeft
---------
10
有关选择哪个 Format-*
cmdlet 的逻辑何时,请参阅这个答案.
For the logic behind which Format-*
cmdlet is chosen when, see this answer.
但是,您可以选择不同的格式化 cmdlet,例如用于列表样式显示的 Format-List
,而不是(隐式)应用的 Format-Table
在单独的行中显示每个属性:
However, instead of the (implicitly) applied Format-Table
, you could have chosen a different formatting cmdlet, such as Format-List
for list-style display that shows each property on its own line:
PS> [pscustomobject] @{ freespace = 100; size = 1000 } |
Select-Object @{label='SpaceLeft'; expression={$_.freespace / $_.size * 100}} |
Format-List
SpaceLeft : 10
然而,当涉及到进一步处理时,Select-Object
和Format-Table
没有创建相等 - 只有 Select-Object
是合适的:
However, when it comes to further processing, Select-Object
and Format-Table
are not created equal - only Select-Object
is suitable:
让我们看看输出对象拥有哪些属性,使用 Get-Member -Type Properties
,首先使用 Select-Object
:
Let's look at what properties the output object(s) possess, using Get-Member -Type Properties
, first with Select-Object
:
PS> ([pscustomobject] @{ freespace = 100; size = 1000 } |
Select-Object @{label='SpaceLeft'; expression={$_.freespace / $_.size * 100}} |
Get-Member -Type Properties).Name
SpaceLeft
正如预期的那样,输出有一个名为 SpaceLeft
的属性,这就是您的 Where-Object
调用可以操作的内容.
As expected, the output has one property, named SpaceLeft
, and that's what your Where-Object
call can operate on.
使用 Format-Table
而不是 Select-Object
讲述了一个不同的故事:
Using Format-Table
instead of Select-Object
tells a different story:
PS> ([pscustomobject] @{ freespace = 100; size = 1000 } |
Format-Table @{label='SpaceLeft'; expression={$_.freespace / $_.size * 100}} |
Get-Member -Type Properties).Name
autosizeInfo
ClassId2e4f51ef21dd47e99d3c952918aff9cd
groupingEntry
pageFooterEntry
pageHeaderEntry
shapeInfo
ClassId2e4f51ef21dd47e99d3c952918aff9cd
groupingEntry
shapeInfo
ClassId2e4f51ef21dd47e99d3c952918aff9cd
formatEntryInfo
outOfBand
writeStream
ClassId2e4f51ef21dd47e99d3c952918aff9cd
groupingEntry
ClassId2e4f51ef21dd47e99d3c952918aff9cd
groupingEntry
这些部分模糊命名的属性具体代表什么并不重要 - 重要的是:
It doesn't really matter what these in part obscurely named properties specifically represent - all that matters is:
它们的唯一目的是被 PowerShell 的输出格式系统解释.
Their sole purpose is to be interpreted by PowerShell's output-formatting system.
传递给 Format-Table
的选定/计算属性不出现在输出中.
The selected / calculated properties passed to Format-Table
are not present as such in the output.
- 这就是您的
Where-Object
调用没有按预期工作的原因:$_.SpaceLeft
引用了一个不存在的属性,因此表达式的计算结果为$null
和$null -lt 10
总是$true
.
- That's why your
Where-Object
call didn't work as intended:$_.SpaceLeft
referenced a non-existing property, so the expression evaluates to$null
, and$null -lt 10
is always$true
.
不管他们的输入是什么,Format-*
cmdlet 都会输出 Microsoft.PowerShell.Commands.Internal.Format.*
表示格式说明的类型.
Irrespective of their input, Format-*
cmdlets output instances of Microsoft.PowerShell.Commands.Internal.Format.*
types that represent formatting instructions.
这篇关于在表结构上添加一个 where 对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!