Powershell: Złaczenie dwóch list po wspólnym kluczu. (Join dwóch list)

27-mar-2016

Zdarza się, że mamy w powershellu do czynienia z dwiema listami. Obie mają np. kolumnę ID i obie listy mają inne kolumny, a twoim zadaniem jest połączyć te dwie listy w jedną. Poniższy skrypt realizuje takie zadanie. Najpierw skrypt, a potem komentarz:

$list1 = Get-Process | select Id, Pm 
$list2 = Get-Process | select Id, Name 
$list3= $list1 | % {`
                     $x = $_ ;`
                     $list2 | % {`
                                  if ($_.Id -eq $x.Id) {`
                                     $_ | Select @{L="Handle";E={$x.Id  }},`
                                                 @{L="Name";  E={$_.Name}},`
                                                 @{L="PM";    E={$x.Pm  }}`
                    }}}
$list3

Do rzeczy. Zaczynamy od 2 list. U nas jest to $list1 i $list2. Obie listy jakoś trzeba było utworzyć, dlatego zainicjowałem je tutaj przez Get-Process. W $list1 Znajdują się tylko 2 właściwości procedu: Id i PM. W liście $list2 też znajdują się 2 właściwości ale są to ID i Name. Naszym zadaniem jest połączenie tch list w jedną, aby można byo odczytać ID, PM i Name.

$list1 = Get-Process | select Id, Pm 
$list2 = Get-Process | select Id, Name

Wynika zapamiętamy w nowej zmiennej $list3. stąd mamy zapis:

$list3 = ...

a na końcu wyświetlenie tej listy:

$list3

No więc pora na najciekawsze. Listę $list1 wysyłamy potokiem do For-Each (zastąpione przez %).  i uruchamiamy ScriptBlok:

$x = $_ ;`
$list2 | % {`
             if ($_.Id -eq $x.Id) {`
                                   $_ | Select @{L="Handle";E={$x.Id  }},`
                                               @{L="Name";  E={$_.Name}},`
                                               @{L="PM";    E={$x.Pm  }}`
            }}

Na początku, dla wygody w zmiennej $x zapamiętujemy bieżący element listy $list1:

$x = $_ ;`

Teraz listę $list2 próbujemy połączyć z bieżącym elementem $x. W tym celu $list2 potokiem przekazujemy do kolejnego For-Each – nowu zastąpione przez % – a w ScriptBlock sprawdzamy, czy elementy tych dwóch list do siebie pasują, czyli czy mają te same Id:

if ($_.Id -eq $x.Id)

Jeśli tak, to wykonujemy:

$_ | Select @{L="Handle";E={$x.Id  }},`
            @{L="Name";  E={$_.Name}},`
            @{L="PM";    E={$x.Pm  }}`

Innymi słowy budujemy obiekt o właściwościach Handle, Name, PM. Handle to Id procesu z listy $list1 (zapamiętany w zmiennej $x), Name to nazwa procesu wzięta z $list2 z bieżącego elementu czyli $_ i wreszcie PM zostało wzięte z $list1 ze zmiennej $x. Polecenie Select dodaje te elemnty do nowej listy $list3.

Gotowe!

 

 

Komentarze:

  1. Kurs Powershell. Informacja dla studentów | Kursy OnlineKursy Online napisał,

    […] Połączenie wartości z dwóch list po kluczu […]

Autor: Rafał Kraik