【问题标题】:Is there a way to get number of groups created by 'Group-Object' cmdlet?有没有办法获取由“Group-Object”cmdlet 创建的组数?
【发布时间】:2022-01-23 23:28:01
【问题描述】:

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

我的任务是递归地在某个位置查找重复文件。我可以毫无问题地做到这一点。但是看到一些文件有 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 文件中,两种分辨率的速度是相当的。有关“测量命令”输出,请参见下文。

基于表达式

基于管道

【问题讨论】:

  • 请使用Group-Object向我们展示您的源代码。使用命令help Group-Object -Full 并查看Example 1
  • excel部分只是为了提供背景
  • 这有帮助吗? stackoverflow.com/a/70380933/15339544此方法使用文件哈希而不是文件名(速度较慢,但​​无论名称如何都会找到实际的重复项)。
  • 之前的评论无效。试试这个:Group -Property 'Compare Filename' | Measure | Select -ExpandProperty Count
  • 如果只有一个组,Group-Object cmdlet 会给出一个单独的 GroupInfo 对象...如果有多个,则给出GroupInfo 对象的集合。所以...将结果强制放入一个数组并获取.Count 值。像这样... >>> @(@($(1..20)) | Group-Object).Count 20。 [咧嘴]

标签: powershell csv group-by numbers


【解决方案1】:

可靠地计算Group-Object 输出的组数(Microsoft.PowerShell.Commands.GroupInfo 实例),请使用以下任一方法:

  • 基于管道,如zett42 所建议的那样;虽然相对较慢,但这会导致 流处理 处理不需要先将所有 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 输出被视为一个数组,即使只有一个 em> 组恰好是输出。

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

    • 鉴于GroupInfo 没有.Length 属性,因此固有的.Length 属性按预期工作。

    • 可以用字符串标量演示相反的情况:'foo'.Length3 - 反映字符数的原生类型 .Length 属性的值 - 而 'foo'.Count1 - 内在 @ 987654358@“计数”单个对象的属性。

  • Measure-Object 的管道解决方案中,由于管道的枚举行为,不会出现问题:但是许多对象 Group-Object 输出通过管道一个接一个发送,@987654361 @ 对它们进行计数 - 在这种情况下,Measure-Object 输出的 始终单个 Microsoft.PowerShell.Commands.GenericMeasureInfo 实例的原生类型 .Count 属性的值 兴趣。

【讨论】:

  • 除了提到的那些之外,LINQ 是一个选项吗?只是出于好奇
猜你喜欢
  • 1970-01-01
  • 2017-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-07
  • 1970-01-01
  • 2018-04-28
相关资源
最近更新 更多