测量多个属性?

use*_*216 1 powershell get-childitem measure powershell-5.1

我想使用 Get-ChildItem 查询目录,并创建一个包含 Path、Size(以 GB 为单位)、MinimumCreationTime、MaximumCreationTime 等列的表。在 foreach 循环中我写了 3 个 Measure 命令。是否可以用一个命令测量多个属性?

$pathes = @'
C:\open
C:\games
'@.Split([System.Environment]::NewLine, [System.StringSplitOptions]::RemoveEmptyEntries)

foreach ($path in $pathes){
    Get-ChildItem $path -Recurse | Measure Length -Sum 
    Get-ChildItem $path -Recurse | Measure CreationTime -Minimum
    Get-ChildItem $path -Recurse | Measure CreationTime -Maximum
    }
Run Code Online (Sandbox Code Playgroud)

zet*_*t42 5

可以通过Measure-Object使用计算属性将CreationTime属性转换为数字类型来单次调用该命令。现在-Sum可以使用它(尽管我们将丢弃 的总和CreationTime)。

计算统计数据后,我们将转换回[DateTime]以获得有意义的显示值。

从 PS 7+ 开始,计算属性可以用作Measure-Object参数。对于较旧的 PS 版本,我们可以使用它Select-Object来创建计算属性。

PS 7+ 解决方案

foreach ($path in $pathes){

    $stats = Get-ChildItem $path -File -Recurse | 
             Measure-Object 'Length', { $_.CreationTime.Ticks } -Sum -Minimum -Maximum

    # Create the output for one table row
    [PSCustomObject]@{
        Path                = $path
        'Size(GB)'          = [math]::Round( $stats[0].Sum / 1GB, 2 )   # 2 = number of digits
        MinimumCreationTime = [DateTime] [Int64] $stats[1].Minimum
        MaximumCreationTime = [DateTime] [Int64] $stats[1].Maximum
    }
}
Run Code Online (Sandbox Code Playgroud)

解释:

  • 我们在调用中指定两个属性Measure-Object
    • 第一个属性只是Length
    • 第二个属性是一个计算属性,这意味着它通过运行一个小脚本块来获取其值。脚本块将 转换CreationTimeInt64并将其用作要测量的值。
  • 当为 指定多个属性时Measure-Object,它会输出一个数组,其中包含每个属性的对象,其中包含统计信息。
    • $stats[0]包含Sum,MinimumMaximum对于Length属性,我们只取Sum.
    • $stats[1]包含Sum,MinimumMaximum对于CreationTime属性,我们只取MinimumMaximum。请注意,Measure-Object产生类型 的输出[double],因此我们首先必须转换回 ,[Int64]然后才能最终转换回[DateTime]

PS 5解决方案

foreach ($path in $pathes){

    $stats = Get-ChildItem $path -File -Force | 
        Select-Object Length, @{ name = 'CreationTimeTicks'; expression = { $_.CreationTime.Ticks } } | 
        Measure-Object Length, CreationTimeTicks -Sum -Minimum -Maximum

    # Create the output for one table row - identical to PS 7+ solution
    [PSCustomObject]@{
        Path                = $path
        'Size(GB)'          = [math]::Round( $stats[0].Sum / 1GB, 2 )   # 2 = number of digits
        MinimumCreationTime = [DateTime] [Int64] $stats[1].Minimum
        MaximumCreationTime = [DateTime] [Int64] $stats[1].Maximum
    }
}
Run Code Online (Sandbox Code Playgroud)

解释:

这与 PS 7+ 解决方案类似,只不过我们用来Select-Object创建一个名为 的计算属性CreationTimeTicks,因此我们可以按名称将其传递给调用Measure-Object

结论

虽然这段代码似乎有效,但这个答案提供的代码在概念上更清晰,所以我会同意它。

  • @zett42 `Measure-Object` 最近才更新为接受属性表达式 (7.x),在此之前(包括在 WPS 的所有版本中)它只接受字符串 - 因此它只支持命名属性,而不支持计算属性 (2认同)