Tom*_*ski 3 arrays powershell object member-enumeration
(Get-ChildItem -File -Recurse -Path $path).Fullname 返回全名
(Get-ChildItem -File -Recurse -Path $path).Name 数组返回文件名数组但
(Get-ChildItem -File -Recurse -Path $path).Length只返回一个值 - 元素数
问题 - 如何将结果作为文件长度数组?
太长了;博士
使用.ForEach()数组方法可以实现简洁且高性能的解决方案:
# Return the files' .Length property values as a collection.
(Get-ChildItem -File -Recurse -Path $path).ForEach('Length')
Run Code Online (Sandbox Code Playgroud)
正如 Mathias 的回答中所指出的,类型本机属性(例如.Length数组实例上的属性)优先于您尝试执行的所谓成员访问枚举,也就是说,您想要收集以下元素的.Length属性值:您的集合(数组;由 输出的实例),并将它们作为 ( )数组返回。System.IO.FileInfoGet-ChildItem[object[]]
%.,以便您可以明确地请求常规属性访问或成员访问枚举。成员访问枚举的一个可能令人惊讶的方面是,它应用了管道逻辑,因为它会根据情况返回一个标量,即如果集合恰好只包含一个元素。
@(Get-Date).Year.GetType().Name返回System.Int32, not Object[],表示返回的是整数而不是包含整数的(单元素)数组。成员访问枚举不仅方便,而且快速,因为它避免了PowerShell 代码中的循环/枚举。
ForEach-ObjectSelect-Object 正如 Mathias 的回答所示,使用或cmdlet绝对是一种功能强大但速度缓慢的解决方法,因为由于使用了pipeline,因此在给定情况下无法使用成员访问枚举,而对于输入来说,这是不必要的那已经在记忆中了。
因此,使用.ForEach()数组方法(使用只需指定目标属性名称( )的重载'Length')是一种简洁且性能更好的替代方法。
.ForEach()是一个集合,尽管不是一个数组:它的类型是[System.Collections.ObjectModel.Collection[psobject]],但是,在大多数情况下,它的行为就像一个数组。[1][1] 与数组不同,这种类型的集合是可扩展的(您可以添加或删除元素)。由于元素类型为[psobject],每个元素通常都无形地包装在该类型中;例如,42 -is [psobject]是$false,但是@(42).ForEach({ $_ })[0] -is [psobject]是$true。不幸的是,在某些情况下,这种几乎不可见的包装器会导致不同的行为 - 请参阅GitHub 问题 #5579。
您获得的一个值确实是结果数组的长度 - Array 类具有一个优先于属性枚举的显式Length属性。
要从Length数组中的每个项目获取单独的属性值,请通过管道连接到Select-Objector ForEach-Object,如下所示:
Get-ChildItem -File -Recurse -Path $path |ForEach-Object -MemberName Length
# or
Get-ChildItem -File -Recurse -Path $path |Select-Object -ExpandProperty Length
Run Code Online (Sandbox Code Playgroud)