Подсчет, сортировка и группировка по в Powershell

#sorting #powershell #grouping #counting

#сортировка #powershell #группировка #подсчет

Вопрос:

Есть ли какие-нибудь интересные командлеты, которые помогут мне сделать следующее? Я хочу что-то в 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 -detail и Get-Help Sort-Object -detail . Начните с этого.

2. @EBGreen, возможно, есть более приятный способ сформулировать это? Get-Help Команда, хотя и является отличной ссылкой на документы, немного похожа на «вы знаете, как использовать документы?». Вместо этого, может быть, что-то вроде приведенного ниже…

3. Хорошей отправной точкой может быть Group-Object и Sort-Object

4. @KyleMit, если бы у меня было время, я бы написал реальный ответ. Иногда у меня просто достаточно времени, чтобы быстро просмотреть некоторые вопросы. В этих случаях, если у меня недостаточно времени для правильного ответа, я предложу что-нибудь в комментарии, чтобы, надеюсь, запустить операцию в правильном направлении, чтобы они могли найти ответ самостоятельно. Чтобы они, по крайней мере, надеялись добиться некоторого прогресса в решении своей проблемы.

Ответ №1:

Вы можете получить группы и подсчеты, используя 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-property и RootElementName, чтобы он был у вас, если вам нужно получить filename rootelement для списка. Если нет, мы могли бы упростить это до:

 $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