Powershell: Dodanie numeru wiersza po Sort-Object (ROW_NUMBER)

14-paź-2014

Polecenie Sort-Object układa obiekty przyjęte z poprzedniego polecenia w zadanej kolejności, np.

Get-Process | Sort -property CPU -Desc

sortuje procesy umieszczając na początku te, które najbardziej obciążyły procesor. Jednak co zrobić, aby zwracane pozycje miały dodatkowo numer wiersza (proces najbardziej obciążający CPU numer 1, kolejny numer 2 itd.)?

Rozwiązanie 1

$i=0

Get-Process | sort -Property cpu -Descending |
select id, processname, @{n=”Row number”;e={$i+=1; $i}}

Fajne, ale nie działa…. w/w polecenie zawsze wyświetli jedynki w kolumnie Row Number. Dlaczego? Wyrażenie e={$i+=1; $i} „nie widzi” zadeklarowanej wcześniej zmiennej $i, Dlatego zawsze $i na początku jest równe 0, potem jest zwiększane o 1 i zwracana jest jedynka. Dzieje się tak dla każdego procesu przechodzącego do polecenia Select.

Zmienną $i można jednak „awansować” na zmienną skryptu:

$script:i=0

Get-Process | sort -Property cpu -Descending |
select id, processname, @{n=”Row number”;e={$script:i+=1; $script:i}}

To działa! Zmienna $script:i jest poprawnie „widziana” przez skrypt i wszelkie wyrażenia w skrypcie. Ta zmienna jest globalna dla całego skryptu!

Rozwiązanie 2

Bazujemy tu o cmdlet Foreach-Object. Dla każdego obiektu zwiększamy wartość $rowNumber, a potem zwracamy wynik przez return $rowNumber,$_

$rowNumber=0

Get-Process | sort -Property cpu -Descending |
% { $rowNumber+=1; return $rowNumber,$_}

Niestety, to nie jest ładne rozwiązanie… zwracana liczba jest niezależna od zwracanego procesu, nawet na ekranie prezentuje się to brzydko…, ale:

Get-Process | sort -Property cpu -Descending |

% { $rowNumber+=1; $ret = $_ | Add-Member -NotePropertyName RowNumber -NotePropertyValue $rowNumber -PassThru; return $ret} |

select Id, Process, RowNumber

zadziała dobrze. Co tu się dzieje? W ForEach-Object do obiektu proces (reprezentowany przez $_) jest dodawana właściwość „RowNumber” o wartości „$rowNumber”. Ponieważ obiekt typu proces nie pozwala na dodawanie właściwości, dodajemy parametr PassThru. Parametr powoduje utworzenie nowego obiektu, który odziedziczył wszystkie właściwości z typu proces i dodał nową właściwość RowNumber.

Natchnienie do rozwiązania numer 2 pochodzi z http://technet.microsoft.com/en-us/library/hh849879.aspx

Komentarze są wyłączone

Autor: Rafał Kraik