【问题标题】:powershell Get-ChildItem result in arraypowershell Get-ChildItem 结果为数组
【发布时间】:2021-08-05 09:01:02
【问题描述】:

(Get-ChildItem -File -Recurse -Path $path).Fullname 返回全名数组 (Get-ChildItem -File -Recurse -Path $path).Name 返回文件名数组 但 (Get-ChildItem -File -Recurse -Path $path).Length 只返回一个值——元素个数

问题 - 如何获取文件长度数组的结果?

【问题讨论】:

  • 请允许我给你一个标准的建议给新手:如果你accept 一个答案,你将帮助未来的读者,向他们展示解决了你的问题的方法。要接受答案,请单击答案左侧大数字下方的大 ✓ 符号(您将获得 2 点声望)。如果您至少有 15 个声望点,您还可以投票给其他有用的答案(也可以选择接受的答案)。如果您的问题尚未解决,请提供反馈,或者,如果您自己找到了解决方案,请self-answer

标签: arrays powershell object member-enumeration


【解决方案1】:

你得到的一个值确实是结果数组的长度 - Array 类有一个显式的Length property,它优先于属性枚举。

要从数组中的每个项目中获取单独的 Length 属性值,请通过管道连接到 Select-ObjectForEach-Object,如下所示:

Get-ChildItem -File -Recurse -Path $path |ForEach-Object -MemberName Length
# or 
Get-ChildItem -File -Recurse -Path $path |Select-Object -ExpandProperty Length

【讨论】:

    【解决方案2】:

    补充Mathias R. Jessen's helpful answer

    tl;dr

    使用.ForEach() array method 可以实现简洁而高效的解决方案:

    # Return the files' .Length property values as a collection.
    (Get-ChildItem -File -Recurse -Path $path).ForEach('Length')
    

    正如 Mathias 的回答中所指出的,type-native properties - 例如数组实例上的.Length - 优先于 所谓的 @您尝试执行的 987654323@ - 也就是说,您想要收集集合中 元素.Length 属性值(数组;System.IO.FileInfo 实例输出的 @987654325 @),并将它们作为 ([object[]]) array 返回。

    • GitHub issue #7445 讨论了这种情况的模糊性,并建议引入一个专用运算符,例如%.,以便您可以明确地请求或者常规属性访问成员枚举。

    成员枚举的一个可能令人惊讶的方面是它应用了管道逻辑,因为它会根据情况返回一个标量,即如果集合恰好包含一个元素

    • 例如,@(Get-Date).Year.GetType().Name 返回的是 System.Int32,而不是 Object[],表示返回的是整数而不是包含整数的(单元素)数组
    • GitHub issue #6802 讨论这个问题。

    成员枚举不仅方便,而且快速,因为它避免了PowerShell代码中的循环/枚举

    使用 ForEach-ObjectSelect-Object cmdlet,如 Mathias 的回答所示,绝对是 一个 功能但是 slow 解决方法 因为使用了 pipeline,因此在给定的情况下无法使用成员枚举,这对于输入来说是不必要的已经在内存中了

    因此,使用.ForEach() array method - 使用重载,您只需指定目标属性name ('Length') - 是一种简洁且性能更好的替代方案

    • 注意:与成员枚举不同,.ForEach()返回值始终是一个集合,尽管不是数组:它是[System.Collections.ObjectModel.Collection[psobject]] 类型,但是在大多数情况下,它的行为类似于数组。[1]

    [1] 与数组不同,这种类型的集合是可扩展的(您可以添加或删除元素)。由于元素类型为[psobject],每个元素通常不可见包裹在这种类型中;例如,42 -is [psobject]$false,但 @(42).ForEach({ $_ })[0] -is [psobject]$true。不幸的是,种情况下,这种近乎不可见的包装器会导致不同的行为 - 请参阅 GitHub issue #5579

    【讨论】:

      【解决方案3】:

      在您的示例中,您将获得结果数组的 Length

      Get-ChildItem -File 返回System.IO.FileInfo 的数组。因此,您需要获取(选择)数组中每个条目的 Length 属性。这是通过使用Select-Object 或仅使用select 完成的:

      Get-ChildItem -File -Recurse  -Path $path | Select-Object Length
      

      这将为您提供一个对象数组,其中包含文件长度为Length 属性。您还可以选择多个属性:

      Get-ChildItem -File -Recurse  -Path $path | Select-Object Name, Length
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-02-22
        • 1970-01-01
        • 2019-02-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多