Sokszor előfordulhat, hogy egyedi objektumokat keresünk, azaz a duplikációkra nem vagyunk kíváncsiak. Például a futó processzek esetében ugyanazokat nem akarom többször látni. Alaphelyzetben ezt a listát kapom:
[45] PS C:\>Get-Process | sort
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
...
0 0 0 28 0 0 Idle
758 20 28864 24160 162 29,53 2504 iexplore
807 24 54592 28636 207 93,50 1296 iexplore
97 3 740 2864 23 0,09 2788 igfxpers
80 3 1216 3572 34 0,16 2532 igfxtray
473 10 4284 1444 43 7,66 1016 lsass
...
Nézzük csak az egyedieket a get-unique segítségével:
[47] PS C:\>Get-Process | get-unique | sort
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
...
0 0 0 28 0 0 Idle
807 24 54592 28636 207 93,50 1296 iexplore
97 3 740 2864 23 0,09 2788 igfxpers
80 3 1216 3572 34 0,16 2532 igfxtray
481 11 4316 1880 43 7,66 1016 lsass
...
Látszik, hogy az iexplorer csak egyszer szerepel a második listámban.
Vajon mit lehet tenni akkor, ha pont a duplikáltakra vagyok kíváncsi? Sajnos nincs „get-duplicate” cmdlet, de ilyen jellegű működést mi magunk is elő tudunk idézni a get-unique és az előbb látott compare-object ötvözetével:
[55] PS C:\>$elemek = "a","b","c","d","e","a","b","a"
[56] PS C:\>Compare-Object ($elemek) ($elemek| sort | Get-Unique)
InputObject SideIndicator
----------- -------------
a <=
b <=
a <=
Nézzük meg ugyanezt a processzekre:
[57] PS C:\> Compare-Object (Get-Process ) (Get-Process| Get-Unique)
InputObject SideIndicator
----------- -------------
System.Diagnostics.Process (conhost) <=
System.Diagnostics.Process (csrss) <=
System.Diagnostics.Process (svchost) <=
System.Diagnostics.Process (svchost) <=
System.Diagnostics.Process (svchost) <=
System.Diagnostics.Process (svchost) <=
System.Diagnostics.Process (svchost) <=
System.Diagnostics.Process (svchost) <=
System.Diagnostics.Process (svchost) <=
System.Diagnostics.Process (svchost) <=
System.Diagnostics.Process (svchost) <=
Természetesen a Get-Unique is az adott objektumon végzett ToString() metódus alapján dönti el az egyediséget, hasonlóan, ahogy a Compare-Object-nél láttuk, azzal a különbséggel, hogy ott meg lehetett adni, hogy mely tulajdonságok alapján vizsgálja az egyformaságot, ha az alapműködés nem tetszett nekünk, itt sajnos ilyet nem lehet. De természetesen ezen is javíthatunk egy saját függvénnyel:
function Get-UniqueProp
([string[]] $property)
{
@($input | Group-Object
-Property $property) |
ForEach-Object
{
$_.group
| Select-Object -First 1 }
}
Ennek a függvénynek ugyanúgy megadható paraméterként, hogy mely tulajdonságok egyformasága esetében érezze azt, hogy két elem egyforma. Nézzünk erre egy példát:
[26] PS C:\> Get-Service | Get-Unique
Status Name DisplayName
------ ---- -----------
Stopped AeLookupSvc Application Experience
[27] PS C:\> Get-Service | Get-UniqueProp -property status
Status Name DisplayName
------ ---- -----------
Stopped AeLookupSvc Application Experience
Running Appinfo Application Information
Ha a szolgáltatásokat betöltöm a „gyári” Get-Unique cmdletbe [26], akkor egy elemet kapok kimenetként, mert minden szolgáltatás-objektum a ToString() meghívásával azt adja, hogy „System.ServiceProcess.ServiceController”, ami mindenütt ugyanaz. Ezzel szemben az én Get-UniqueProp cmdletemnél megadott Status tulajdonság alapján egy futó és egy nem futó szolgáltatást kaptam.