Jak pobrać powtarzające się elementy z listy za pomocą programu PowerShell?
Skrypciarze odpowiadają na Wasze pytania
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! 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ść, 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 |