在Powershell中进行计数、排序和分组

10
有没有一些很酷的cmdlet可以帮助我做以下事情?我想要在Powershell中做同样简单的SQL操作。
select RootElementName , count(*) from Table
group by RootElementName 
order by RootElementName 

我在一个目录中找到所有XML文件,并查找每个XML文件的根元素。
$DirectoryName = "d:\MyFolder\"
$AllFiles = Get-ChildItem $DirectoryName -Force 
foreach ($Filename in $AllFiles) 
{
     $FQFilename = $DirectoryName + $Filename
     [xml]$xmlDoc = Get-Content $FQFilename
     $rootElementName = $xmlDoc.SelectSingleNode("/*").Name; 
     Write-Host $FQFilename $rootElementName 
}

期望结果:

RootName   Count 
--------   -----
Root1      15 
MyRoot     16 
SomeRoot   24 

我知道我可以创建两个数组或一个对象数组,将根元素存储在其中,并使用典型的代码进行计数,只是希望这种新语言可能有些内置功能我还没有发现。
我能把"Write-Host $FQFilename $rootElementName "导向某些行为类似于我上面提到的SQL的东西吗?

1
在 PowerShell 提示符下,键入:Get-Help Group Object -detailGet-Help Sort-Object -detail。从那里开始。 - EBGreen
1
@EBGreen,有没有更好的措辞方式?Get-Help命令虽然是文档的好参考,但有点像“你会使用文档吗?”。也许可以用以下方式表达... - KyleMit
2
一个很好的起点可能是 Group-ObjectSort-Object - KyleMit
@KyleMit,如果我有时间的话,我会写一个真正的答案。有时候我只有足够的时间快速浏览一些问题。在这种情况下,如果我没有足够的时间来给出一个适当的答案,我会在评论中建议一些东西,希望能让OP朝着正确的方向开始寻找答案,以便他们可能自己找到答案。这样他们至少有希望在解决问题上取得一些进展。 - EBGreen
1个回答

16

您可以使用Group-Object来获取分组和计数,例如:

$AllFiles | Group-Object RootElementName | Sort-Object Name | Select-Object Name, Count

在您当前的示例中,Write-Host不会写入可排序或分组的管道对象。Write-Host仅向屏幕打印文本以向用户显示内容,例如脚本菜单。

$DirectoryName = "d:\MyFolder\"
$AllFiles = Get-ChildItem $DirectoryName -Force | ForEach-Object {
    #The FullName-property contains the absolute path, so there's no need to join the filename and $directoryname
    [xml]$xmlDoc = Get-Content $_.FullName
    $rootElementName = $xmlDoc.SelectSingleNode("/*").Name

    #Outputing an object that we can group and sort
    New-Object -TypeName psobject -Property @{
        FileName = $_.FullName
        RootElementName = $rootElementName
    }
}
$grped = $AllFiles | Group-Object RootElementName | Sort-Object Name | Select-Object Name, Count

我正在创建一个带有FileName属性和RootElementName的对象,这样如果您需要检索列表的文件名+根元素,则可以轻松获取。如果不需要,我们可以简化为:

我创建了一个带有 FileName 属性和 RootElementName 的对象,以便在需要检索列表的文件名和根元素时,您可以方便地使用它。否则,我们可以将其简化为:

$DirectoryName = "d:\MyFolder\"
$AllFiles = Get-ChildItem $DirectoryName -Force | ForEach-Object {
    #The FullName-property contains the absolute path, so there's no need to join the filename and $directoryname
    [xml]$xmlDoc = Get-Content $_.FullName

    #Output rootelementname
    $xmlDoc.SelectSingleNode("/*").Name
} 
$grped = $AllFiles | Group-Object | Sort-Object Name | Select-Object Name, Count

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