有没有办法获取 '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'.Length
是 3
- 类型原生的值 .Length
属性反映字符数 - 而 'foo'.Count
是 1
- 内在的 .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
输出 是 感兴趣的值。
我很确定答案是否定的,但它一直困扰着我。
我的任务是在某个位置递归地查找重复文件。我可以毫无问题地做到这一点。但是由于有些文件有 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'.Length
是3
- 类型原生的值.Length
属性反映字符数 - 而'foo'.Count
是1
- 内在的.Count
属性 “计算”单个对象。
在具有
Measure-Object
the problem doesn't arise due to the pipeline's enumeration behavior: however many objectsGroup-Object
outputs are sent one by one through the pipeline, andMeasure-Object
counts them - and in this case the value of the type-native.Count
property of the always singleMicrosoft.PowerShell.Commands.GenericMeasureInfo
实例的管道解决方案中,Measure-Object
输出 是 感兴趣的值。