有没有办法获取 'Group-Object' cmdlet 创建的组数?

Is there a way to get number of groups created by 'Group-Object' cmdlet?

我很确定答案是否定的,但它一直困扰着我。

我的任务是在某个位置递归地查找重复文件。我可以毫无问题地做到这一点。但是由于有些文件有 3 或 4 个重复项,我无法回答“有多少文件是原件?”的问题。无需诉诸 excel 编辑。

代码:

gci -path $path -recurse -file -erroraction silentlycontinue|
Select @{l='Original Filename';e={$_.PSChildName}}, @{l='Compare Filename';e={$_.BaseName.replace('_','*').replace(' ','*').replace('-','*')}}, @{l="Path";e={$_.PSParentPath.Substring(38,$_.PSParentPath.Length-38)}}, @{l="Link";e={$_.FullName}}|
group -Property 'Compare Filename'|
Where {$_.count -ge 2}|
%{$_.group}|
Export-Csv -Path $path2 -NoTypeInformation

路径变量无关紧要,所以我不会列出它们。

编辑: 我已经测试了提供的两种解决方案,并阅读了 mklement0 提供的精彩解释。 最后,至少对于我正在处理的 ~4k 文件,两种分辨率的速度是相当的。请参阅下面的 'measure-command' 输出。

基于表达式

基于流水线

可靠地统计组数(Microsoft.PowerShell.Commands.GroupInfo instances) that Group-Object输出,使用以下任一方法:

  • 基于管道,如zett42所建议;虽然相对较慢,但这导致 streaming 处理不需要首先在内存中收集所有 Group-Object 输出:
(1, 1, 1 | Group-Object | Measure-Object).Count  # -> 1 (group)
  • 简洁,基于表达,如Lee Dailey所建议;请注意,这涉及首先收集内存中的所有输出对象:
@(1, 1, 1 | Group-Object).Count   # -> 1 (group)

# Alternative, using .Length
(1, 1, 1 | Group-Object).Length   # -> 1 (group)

注:

  • 要计算所有原始(非重复)对象,即属于自己一组的对象,只需将 | Where-Object Count -eq 1 附加到上面的 Group-Object

  • @()array-subexpression operator 的使用在这种情况下至关重要:它确保 Group-Object 输出被视为 array即使恰好只输出一个single

    • 这确保查询的是 数组的 .Count 属性 而不是单个 GroupInfo 实例的 own .Count 属性 - 反映组成员的数量,在上面的示例中为 3(尝试 (1, 1, 1 | Group-Object).Count)。
  • 或者,使用 .Length 而不是 .Count 绕过此命名冲突: .Length.Count 是彼此的别名,并且都提供作为intrinsic properties甚至在标量(单个对象)上,作为PowerShell中标量和集合统一处理的一部分:也就是说, PowerShell 甚至可以显示任何 单个对象 ,其中 .Length / .Count 属性指示该对象的计数,根据定义,该对象的计数为 1 - 除非被同名.

    的本地类型属性抢占
    • 内在的 .Length 属性 因此按预期工作,因为 GroupInfo 没有 .Length 属性.

    • 逆向场景可以用字符串标量来演示:'foo'.Length3 - 类型原生的值 .Length 属性反映字符数 - 而 'foo'.Count1 - 内在的 .Count 属性 “计算”单个对象。

  • 在具有 Measure-Object the problem doesn't arise due to the pipeline's enumeration behavior: however many objects Group-Object outputs are sent one by one through the pipeline, and Measure-Object counts them - and in this case the value of the type-native .Count property of the always single Microsoft.PowerShell.Commands.GenericMeasureInfo 实例的管道解决方案中,Measure-Object 输出 感兴趣的值。