Csoportosítás (Group-Object)

A Group-Object  cmdlet segítségével egy (vagy több) megadott tulajdonság értéke szerint csoportosíthatunk objektumokat. A csoportokba az azonos tulajdonságértékkel rendelkező objektumok kerülnek.

Készítsünk listát, amely az „g” betűvel kezdődő cmdleteket csoportosítja ige szerint! A cmdleteket lekérdező Get-Command kimenetét a Group-Object-nek kell megkapnia, paraméterként pedig meg kell adnunk, hogy melyik tulajdonság értékei szerint akarjuk elvégezni a csoportosítást, ez a Verb tulajdonság lesz:

PS C:\> get-command g* -commandtype cmdlet | group-object -property verb

 

Count Name                      Group

----- ----                      -----

  145 Get                       {Get-Acl, Get-Alias, Get-AppLockerFileInfor...

    1 Group                     {Group-Object}

A csoportok és a bennük található elemek száma jól látható, de maga a csoport tagsága ebben a nézetben nem igazán kivehető, ha túl sok az adott csoportban található elem.

Megjegyzés

A csoportokat alaphelyzetben csak maximum 4 elemig jeleníti meg a PowerShell, feltéve, hogy a konzol szélessége ezt megengedi. Ha ennél több elemet is meg akarunk jeleníttetni, akkor a $FormatEnumerationLimit automatikus változó értékét kell átállítani.

Hogy a képernyőszélesség ne legyen korlát, az egészet még táblázatosan formázom tördeléses módon:

[12] PS C:\> $FormatEnumerationLimit = 8

[13] PS C:\> Get-Command g* -CommandType cmdlet | Group-Object -Property verb |

 Format-Table -Wrap

 

Count Name                      Group

----- ----                      -----

   46 Get                       {Get-Acl, Get-Alias, Get-AuthenticodeSignature

                                , Get-ChildItem, Get-Command, Get-ComputerRest

                                orePoint, Get-Content, Get-Counter...}

    1 Group                     {Group-Object}

A kimeneten látszik, hogy most az első csoportban 8 elem vált láthatóvá.

Még olyat is lehet csinálni a Group-Object segítségével, hogy egyszerre több szempont szerinti csoportot is létrehozhatunk:

[60] PS C:\> get-process | Group-Object -Property processname, company

 

Count Name                      Group

----- ----                      -----

    3 conhost, Microsoft Cor... {System.Diagnostics.Process (conhost), Syst...

    2 csrss, Microsoft Corpo... {System.Diagnostics.Process (csrss), System...

    1 dfsrs, Microsoft Corpo... {System.Diagnostics.Process (dfsrs)}

    1 dfssvc, Microsoft Corp... {System.Diagnostics.Process (dfssvc)}

    1 dns, Microsoft Corpora... {System.Diagnostics.Process (dns)}

    1 dwm, Microsoft Corpora... {System.Diagnostics.Process (dwm)}

A fenti paranccsal, a processzek neve és gyártójuk alapján, együttesen csoportosítottam a futó folyamatokat. Ez nem igazi kétszintű csoportosítás, hanem képez egy „látszólagos” tulajdonságot, amely a processz nevéből és gyártójából áll, és ezen összetett tulajdonság alapján csoportosít.

Ha nincs szükségünk az egyes elemekre, csak a csoportokra, akkor használhatjuk a ‑NoElement kapcsolót:

[21] PS C:\> get-process | Group-Object -Property company -noelement

 

Count Name

----- ----

   38 Microsoft Corporation

    2

    2 Sun Microsystems, Inc.

A fenti példában csak a gyártókra voltam kíváncsi és a darabszámokra.

Alaphelyzetben a Group-Object kimenete egy gyűjtemény, nézzük meg, hogy egy-egy eleme ennek hogyan is néz ki:

[70] PS C:\> $csoportok = get-command g* -commandtype cmdlet | group-object -pr

operty verb

[71] PS C:\> $csoportok[0]

 

Count Name                      Group

----- ----                      -----

   46 Get                       {Get-Acl, Get-Alias, Get-AuthenticodeSignat...

 

 

[72] PS C:\> $csoportok[1]

 

Count Name                      Group

----- ----                      -----

    1 Group                     {Group-Object}

Ebből kinyerhetők az egyes csoportosított elemek a következő módon:

[81] PS C:\> $csoportok[0].group

 

CommandType     Name                            Definition

-----------     ----                            ----------

Cmdlet          Get-Acl                         Get-Acl [[-Path] <String[]>...

Cmdlet          Get-Alias                       Get-Alias [[-Name] <String[...

Cmdlet          Get-AuthenticodeSignature       Get-AuthenticodeSignature [...

Cmdlet          Get-ChildItem                   Get-ChildItem [[-Path] <Str...

Cmdlet          Get-Command                     Get-Command [[-ArgumentList...

Ennél egyszerűbb módja is van ennek, ha arra kérjük a Group-Object-et, hogy ne gyűjteményt készítsen nekünk, hanem hashtáblát:

[82] PS C:\> $csoportok = get-command g* -commandtype cmdlet | group-object -pr

operty verb -AsHashTable

[83] PS C:\> $csoportok

 

Name                           Value

----                           -----

Get                            {Get-Acl, Get-Alias, Get-AuthenticodeSignatu...

Group                          {Group-Object}

 

 

[84] PS C:\> $csoportok.get

 

CommandType     Name                            Definition

-----------     ----                            ----------

Cmdlet          Get-Acl                         Get-Acl [[-Path] <String[]>...

Cmdlet          Get-Alias                       Get-Alias [[-Name] <String[...

Cmdlet          Get-AuthenticodeSignature       Get-AuthenticodeSignature [...

Cmdlet          Get-ChildItem                   Get-ChildItem [[-Path] <Str...

Cmdlet          Get-Command                     Get-Command [[-ArgumentList...

Látható, hogy a –AsHashTable kapcsolóval ezt elérhetjük, így sokkal egyszerűbb az egyes csoportokba sorolt elemeket elérni.

Ezekből a példákból még az is kiderülhetett számunkra, hogy a Group-Object használata előtt nem kell külön sorba rendezni a csővezetéken érkező objektumokat, hogy a csoportok jól kialakuljanak. Emlékezhetünk a format-table cmdlet ‑groupby paraméterére az 1.2.17 Egyszerű formázás fejezetből, ott azt láthattuk, hogy a format-table számára előbb sorba kellett rendezni az objektumokat, hogy jó legyen a csoportosítás. Itt ilyesmire nincs szükség, hiszen a Group-Object halmazokat készít, nem csak megjeleníti a csoportokat.

Hasonlóan a Sort-Object-hez, a Group-Object-el is lehet nem létező tulajdonságok alapján csoportosítani, ha tulajdonságként egy szabályt adunk:

PS C:\> Get-ChildItem C:\PowerShell\ | Group-Object -Property {$_.name.length}

| Sort-Object -Property {[int]$_.Name} -Descending

 

Count Name                      Group

----- ----                      -----

    1 20                        {BigEndianUnicode.txt}

    2 19                        {CheckDynamParam.ps1, test-credential.ps1}

    1 18                        {BigEndianUTF32.txt}

    1 17                        {wait-debugger.ps1}

    1 16                        {CheckNewVars.ps1}

    1 14                        {runasadmin.ps1}

    5 13                        {debug-job.ps1, ékezetes1.txt, ékezetes2.tx...

    1 12                        {BreakAll.ps1}

    4 11                        {Default.txt, Unicode.txt, Unknown.txt, áll...

    1 10                        {String.txt}

    2 9                         {Ascii.txt, UTF32.txt}

    5 8                         {20150923, Byte.txt, fact.ps1, UTF7.txt...}

    2 7                         {job.ps1, Oem.txt}

    1 6                         {Carbon}

Itt a fájlok nevének hossza alapján csoportosítottam a fájlokat. A Group-Object-nél megadott szabályt már alkalmaztam az előző fejezetben. Majd a csoportokat szeretném rendezni a hosszak csökkenő sorrendjében. Sajnos a Name tulajdonság alá került hosszak, bár alaphetően számok voltak, de az eredményben szöveggé alakítja azokat a Group-Object, így a sorba rendezés nem lenne jó. Szerencsére itt is tudjuk alkalmazni a már látott lehetőséget, és inkább rendezzük az egész számmá konvertált Name tulajdonság szerint.



Word To HTML Converter