测量多个属性?
Measure multiple properties?
我想使用 Get-ChildItem 查询一个目录并创建一个 table,其中包含 Path、Size(in 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
}
Is it possible Measure multiple properties with one command?
是的,你可以 - 只是不是你需要的方式。
我们不能在这里完全合并所有三个调用的原因是 Measure-Object
将在 每个输入 [=32] 上执行 所有请求的计算 =] - 它无法有意义地计算多个 [datetime]
值的总和。
所以充其量,我们可以只用 2 轮管道到 Measure-Object
:
$paths = 'C:\open','C:\games'
foreach ($path in $paths){
# Let's call Get-ChildItem ONCE, and store the result
$children = Get-ChildItem $path -Recurse
# Now let's do our calculations
$fileSize = $children | Measure Length -Sum
$newAndOld = $children | Measure CreationTime -Minimum -Maximum
# And finally create a new object to hold the details we calculated above
[pscustomobject]@{
Path = $path
TotalSize = $fileSize.Sum
OldestFileTime = $newAndOld.Minimum
NewestFileTime = $newAndOld.Maximum
}
}
PowerShell 在显示具有 4 个或更少属性的对象时将默认为 table 格式,因此您可以预期 shell 中的默认输出如下所示(取决于语言环境):
Path TotalSize OldestFileTime NewestFileTime
---- --------- -------------- --------------
C:\open 1234567890 1/1/2018 2:00:00 AM 1/31/2021 7:45:00 PM
C:\games 1234567890 1/1/2018 2:00:00 AM 1/31/2021 7:45:00 PM
可以通过一次调用 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
}
}
解释:
- 我们在
Measure-Object
的调用中指定了两个属性:
- 第一个 属性 只是
Length
- 第二个 属性 是一个 calculated property,这意味着它从 运行 一个小脚本块中获取它的值。脚本块将
CreationTime
转换为 Int64
并将其用作将要测量的值。
- 当为
Measure-Object
指定多个属性时,它输出一个数组,其中包含每个 属性 的对象,其中包含统计信息。
$stats[0]
包含Sum
、Minimum
和Maximum
为Length
属性,其中我们只取Sum
.
$stats[1]
包含Sum
、Minimum
和Maximum
为CreationTime
属性,其中我们只取Minimum
和 Maximum
。注意 Measure-Object
产生类型 [double]
的输出,所以我们首先必须转换回 [Int64]
最后转换回 [DateTime]
.
PS5个解
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
}
}
解释:
这类似于PS 7+的解决方案,只是我们使用Select-Object
创建了一个名为CreationTimeTicks
的计算属性,所以我们可以通过它Measure-Object
调用的名称。
结论
虽然此代码似乎有效,但 提供的代码在概念上更清晰,所以我会接受它。
我想使用 Get-ChildItem 查询一个目录并创建一个 table,其中包含 Path、Size(in 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
}
Is it possible Measure multiple properties with one command?
是的,你可以 - 只是不是你需要的方式。
我们不能在这里完全合并所有三个调用的原因是 Measure-Object
将在 每个输入 [=32] 上执行 所有请求的计算 =] - 它无法有意义地计算多个 [datetime]
值的总和。
所以充其量,我们可以只用 2 轮管道到 Measure-Object
:
$paths = 'C:\open','C:\games'
foreach ($path in $paths){
# Let's call Get-ChildItem ONCE, and store the result
$children = Get-ChildItem $path -Recurse
# Now let's do our calculations
$fileSize = $children | Measure Length -Sum
$newAndOld = $children | Measure CreationTime -Minimum -Maximum
# And finally create a new object to hold the details we calculated above
[pscustomobject]@{
Path = $path
TotalSize = $fileSize.Sum
OldestFileTime = $newAndOld.Minimum
NewestFileTime = $newAndOld.Maximum
}
}
PowerShell 在显示具有 4 个或更少属性的对象时将默认为 table 格式,因此您可以预期 shell 中的默认输出如下所示(取决于语言环境):
Path TotalSize OldestFileTime NewestFileTime
---- --------- -------------- --------------
C:\open 1234567890 1/1/2018 2:00:00 AM 1/31/2021 7:45:00 PM
C:\games 1234567890 1/1/2018 2:00:00 AM 1/31/2021 7:45:00 PM
可以通过一次调用 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
}
}
解释:
- 我们在
Measure-Object
的调用中指定了两个属性:- 第一个 属性 只是
Length
- 第二个 属性 是一个 calculated property,这意味着它从 运行 一个小脚本块中获取它的值。脚本块将
CreationTime
转换为Int64
并将其用作将要测量的值。
- 第一个 属性 只是
- 当为
Measure-Object
指定多个属性时,它输出一个数组,其中包含每个 属性 的对象,其中包含统计信息。$stats[0]
包含Sum
、Minimum
和Maximum
为Length
属性,其中我们只取Sum
.$stats[1]
包含Sum
、Minimum
和Maximum
为CreationTime
属性,其中我们只取Minimum
和Maximum
。注意Measure-Object
产生类型[double]
的输出,所以我们首先必须转换回[Int64]
最后转换回[DateTime]
.
PS5个解
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
}
}
解释:
这类似于PS 7+的解决方案,只是我们使用Select-Object
创建了一个名为CreationTimeTicks
的计算属性,所以我们可以通过它Measure-Object
调用的名称。
结论
虽然此代码似乎有效,但