Centrum skryptów - Systemy operacyjne

Jak pobrać powtarzające się elementy z listy za pomocą programu PowerShell?

Udostępnij na: Facebook

Skrypciarze odpowiadają na Wasze pytania

Cześć Skrypciarze!

Witamy w rubryce TechNet, w której Skrypciarze z firmy Microsoft odpowiadają na częste pytania dotyczące używania skryptów w administracji systemu. Jeśli macie jakieś pytania z tej dziedziny, zachęcamy do wysłania e-maila na adres: scripter@microsoft.com. Nie możemy zagwarantować odpowiedzi na każde otrzymane pytanie, ale staramy się jak możemy.

Jak pobrać powtarzające się elementy z listy za pomocą programu PowerShell?

Cześć Skrypciarze! Pytanie

Cześć, Skrypciarze! Rozumiem, że mogę użyć Windows PowerShell i cmdletu Get-Unique, by sprawdzić, które elementy są w danej kolekcji unikatowe. Chcę jednak zrobić coś przeciwnego – sprawdzić, które elementy się powtarzają. Jak to zrobić?

-- YE

Cześć Skrypciarze! Pytanie

Cześć, YE! Wczoraj, jak szykowałem się już do domu, przyszła do nas paczka pełna prezentów dla zwycięzców Olimpiady Skrypciarskiej Olimpiady Skrypciarskiej 2008 od nikogo innego, jak samego Dona Jonesa z Sapien Technologies (j.ang.). Nie powiem, żeby było to niespodziewane, wpadłem jednak trochę w konsternację, przeglądając listę z zawartością paczek, na której oprócz zwyczajowych koszulek, notatników, pióra znalazłem… małpy. Nie wiem, co to miało oznaczać i trochę w sumie się przeląkłem, że skoro na małpach nie ma zwykle napisu, że nie można przewozić ich bez tlenu, ktoś mógłby się nie domyślić i rzeczywiście taką zapakować. Oznaczałoby to dla nas nic innego, jak karton zdechłych małp. Tak, to zdecydowanie jest to, co ludzie lubią najbardziej otrzymywać w prezencie: „jakie masz marzenie synku?”, „A wiesz co tato, kup mi zdechłą małpę.” Dzięki, Don!

W końcu jednak ciekawość nie wytrzymała i otworzyliśmy karton z małpami (każde z nas miało oczywiście na twarzy maseczkę w obawie bliskich spotkań trzeciego stopnia z trupami małp). Okazało się, że małpy nie tylko nie są żywe, ale w ogóle nigdy żywe nie były. Powiem wprost – były to lalki Flingshot Flying Monkeys (j.ang.). Pamiętajcie, by włączyć głośniczki przed wejściem na tę stronę!

A teraz powróćmy do skryptu, bo choć zdaję sobie sprawę, że małpy są dość ekscytujące, to ekscytująca może także być kolekcja różnych gatunków ciast:

Apple

Peach

Chocolate

Chocolate

Apple

Banana Cream

Apple

Blackberry

Pecan

Lemon Meringue

French Silk

Apple

Pecan

Raspberry

Strawberry

Key Lime

Apple

Pecan

YE chciałby wiedzieć, które z tych elementów nie są unikatowe. To znaczy, które z nich pojawiają się więcej niż raz. Jak wykorzystać program Windows PowerShell w celu zidentyfikowania tych elementów nieunikatowych? Może w taki sposób:

$arrPies = "Apple", "Peach", "Chocolate", "Chocolate", "Apple", "Banana Cream",`

     "Apple", "Blackberry", "Pecan", "Lemon Meringue", "French Silk", "Apple", `

     "Pecan", "Raspberry", "Strawberry", "Key Lime", "Apple", "Pecan"

 

$arrPies | Group-Object | Where-Object {$_.Count -gt 1}

Ten skrypt nie jest za bardzo skomplikowany. W pierwszym wierszu dodajemy tylko listę ciast do tablicy $arrPies. W drugim bierzemy tę tablicę i dodajemy ją do cmdletu Group-Object. On już pobierze całą kolekcję i przesortuje wszystkie ciasta w grupy, zapisując liczbę ciast w każdej grupie. Innymi słowy, powinniśmy otrzymać następującą informację:

Count Name                      Group

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

    5 Apple                     {Apple, Apple, Apple, Apple...}

    1 Peach                     {Peach}

    2 Chocolate                 {Chocolate, Chocolate}

    1 Banana Cream              {Banana Cream}

    1 Blackberry                {Blackberry}

    3 Pecan                     {Pecan, Pecan, Pecan}

    1 Lemon Meringue            {Lemon Meringue}

    1 French Silk               {French Silk}

    1 Raspberry                 {Raspberry}

    1 Strawberry                {Strawberry}

    1 Key Lime                  {Key Lime}

Skąd więc wiemy, które elementy nie są unikatowe? Nic trudnego. Count informuje nas, ile jest ciast w danej grupie i jeżeli liczba ta jest większa od 1 to oznacza, że element nie jest unikatowy.

Moglibyśmy teraz przejrzeć nasze dane i wypisać, które elementy nie są unikatowe. W dobie komputerów uważamy jednak, że powinien zająć się tym skrypt. Zatem po zakończeniu pracy obiektu, korzystamy z cmdletu Where-Object:

Where-Object {$_.Count -gt 1}

Filtrujemy tu całą zawartość tablicy, oprócz grup, których właściwość Count jest większa (-gt) niż 1. Da to nam podobny wynik:

Count Name                      Group

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

    5 Apple                     {Apple, Apple, Apple, Apple...}

    2 Chocolate                 {Chocolate, Chocolate}

    3 Pecan                     {Pecan, Pecan, Pecan}

Proste, prawda? Ale nie wylewajmy dziecka kąpielą, chodziło nam przecież tylko o nazwę ciast nieunikatowych. Na nic nam ich liczba (Count) ani grupa (Group). Mając to na uwadze, bierzemy nasze unikatowe „ciastodane” i dodajemy je do cmdletu Select-Object:

$arrPies | Group-Object | Where-Object {$_.count -gt 1} | Select-Object Name

Jak sami widzicie, obiekt Select-Object zwraca nam tu wartości z pojedynczym parametrem – nazwy (Name) Nasz wynik powinien wyglądać w następujący sposób:

Name

----

Apple

Chocolate

Pecan

Załóżmy teraz, że chcielibyśmy uzyskać ciasta unikatowe. W takim wypadku używamy następującego kodu:

$arrPies | Group-Object | Where-Object {$_.count -eq 1} | Select-Object Name

Tym razem instruujemy obiekt Where-Object, aby odfiltrował wszystko oprócz grup, gdzie licznik jest różny od 1 to:

Where-Object {$_.count -eq 1}

Wynik powinien teraz wyglądać w sposób następujący:

Name

----

Peach

Banana Cream

Blackberry

Lemon Meringue

French Silk

Raspberry

Strawberry

Key Lime

Niezłe, nie?

Dodajmy jeszcze, że dane uzyskane w ten sposób są inne niż moglibyśmy uzyskać za pomocą cmdletu Get-Unique. (Jak pamiętamy, YE wspomniał o Get-Unique w pytaniu.) Przedstawiony przez nas skrypt ogranicza wynik do grup, których właściwość Count ma wartość 1. Get-Unique natomiast wyświetla jedno wystąpienie każdego elementu niezależnie od jego wartości Count. Innymi słowy, wynik byłby taki:

Apple

Banana Cream

Blackberry

Chocolate

French Silk

Key Lime

Lemon Meringue

Peach

Pecan

Raspberry

Strawberry

A oto kod użyty do utworzenia tej listy. Zauważmy, że Get-Unique wymaga przesortowania danych przed przekazaniem ich w dół potoku:

($arrPies | Sort-Object) | Get-Unique

Mamy nadzieję, że to odpowiada na Twoje pytanie, YE. Uważamy, że nasza odpowiedź w pełni zasługuje na małpkę, a przynajmniej na lalkę Dra Scripto, tudzież PowerShell Plus, PowerShell Analyzer... Naszym zdaniem jednak małpka jest zdecydowanie najfajniejsza.

 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne