基于子字符串的 Powershell 分组计数项

4

我有一个数据数组,是从一个包含多个元素的命令中获取的。每个项目的名称元素都以三个或四个字符的标识符开头,后跟连字符。我想获得数组中包含相同标识符的所有项目的计数。

使用以下PowerCLI(VMware)命令收集数据:

$items = Get-Datastore <Datastore Name> | Get-VM

数据示例:
NAME     STATUS     INFO     DETAIL
ABC-1234-XXXX     PoweredOn     Info     Detail
ABC-1235-XXXX     PoweredOn     Info     Detail
ABC-1236-XXXX     PoweredOn     Info     Detail
BCA-1234-XXXX     PoweredOn     Info     Detail
BCA-1235-XXXX     PoweredOn     Info     Detail
CBA-1234-XXXX     PoweredOn     Info     Detail
CBA-1235-XXXX     PoweredOn     Info     Detail
CBA-1236-XXXX     PoweredOn     Info     Detail
CBA-1237-XXXX     PoweredOn     Info     Detail

我希望脚本能够给我类似以下的内容:

我需要一个类似于以下的东西:

NAME     COUNT
ABC     3
BCA     2
CBA     4

我很抱歉,我看不懂您说的话。请问您需要哪种语言的翻译呢?
$array = $items | Group Name

计数:

$array.count

编辑:添加数据收集命令


1
你的表格是来自于PowerShell命令还是其他不规范的可执行文件? - Maximilian Burszley
答案将取决于您如何获取这些数据(请更新您的问题,以便回答@TheIncorrigible1的问题)。 - Bill_Stewart
@Bill_Stewart:问题已更新。 - McKenning
2个回答

9
你很接近了,但你不想按完整名称分组 - 你想在“name”处拆分并仅取第一个[0]元素。
这可以在{script block}内作为计算属性进行“即时”操作。在这里,组是期望的结果,在其他情况下(对不存在的属性进行排序),它不会在现有数据中留下痕迹。
以下逐步展示了数据的转换过程:
$items = Get-Datastore <Datastore Name> | Get-VM
$Items

NAME          STATUS    INFO DETAIL
----          ------    ---- ------
ABC-1234-XXXX PoweredOn Info Detail
ABC-1235-XXXX PoweredOn Info Detail
ABC-1236-XXXX PoweredOn Info Detail
BCA-1234-XXXX PoweredOn Info Detail
BCA-1235-XXXX PoweredOn Info Detail
CBA-1234-XXXX PoweredOn Info Detail
CBA-1234-XXXX PoweredOn Info Detail
CBA-1234-XXXX PoweredOn Info Detail
CBA-1234-XXXX PoweredOn Info Detail

$Items | Group-Object {$_.Name.Split('-')[0]}

Count Name Group
----- ---- -----
    3 ABC  {@{NAME=ABC-1234-XXXX; STATUS=PoweredOn; INFO=Info; DETAIL=Detail}, ...
    2 BCA  {@{NAME=BCA-1234-XXXX; STATUS=PoweredOn; INFO=Info; DETAIL=Detail}, ...
    4 CBA  {@{NAME=CBA-1234-XXXX; STATUS=PoweredOn; INFO=Info; DETAIL=Detail}, ...

$Items | Group-Object {$_.Name.Split('-')[0]} | Select-Object Name,Count

Name Count
---- -----
ABC      3
BCA      2
CBA      4

使用Group-Object -NoElement进行编辑将只留下重新排序的最后一步。

2
这是一个不错的方法,但如果您包括有关正在发生的事情(在脚本块(构造属性)上进行分组等)的解释,那么它将是一个很好的答案。 - briantist
感谢回答,LotPings。我能够将您的代码行插入到更大的脚本中,并实现我需要的功能。 - McKenning

7
如果您的项目数组名为$items,列名为Name,那么这个应该可以工作。 $items | %{($_.Name -split "-")[0]} | group | select Name,Count 简单来说,你正在将元素传递到ForEach-Object中,在那里您通过字符-拆分$_.Name,获取第一个元素并将其传递给Group-Object,然后选择NameCount属性。

1
不需要使用ForEach,您可以按计算属性分组。 - user6811411
非常好!我不知道那个。 - langstrom
很棒的答案。我选择了LotPing的答案,因为它更正确。 - McKenning

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接