Triki z PowerShellem #9 – Potokowanie

2008-08-03 17:33

Jedną z głównych zalet powłok tekstowych w rodzaju PowerShella jest to, że pozwalają one na łączenie ze sobą małych, elementarnych poleceń w jedno duże zadanie. Gdy odbywa się to na zasadzie przekazywania wyników jednego programu na wejście następnego, mówimy o potokowaniu (pipelining). Znawcy basha mogliby rzucić np. takim przykładem:

  1. cat < program.cpp | grep int | wc --lines[/code]
  2. w którym to najpierw odczytywana jest zawartość pliku (<kbd>cat</kbd>), wyszukiwane są wszystkie linijki zawierające ciąg "int" (<kbd>grep</kbd>) i liczona jest ich ilość (<kbd>wc</kbd>). Całkiem oczywiste, prawda? ;-)
  3.  
  4. W PowerShellu przetwarzanie potokowe jest o tyle lepsze niż w innych powłokach, że między poleceniami wymienia się nie tekst, a obiekty .NET-owe. Dobrze byłoby więc wiedzieć, jak należy pisać własne skrypty, aby mogły one działać w potokach. Na szczęście nie jest to specjalnie trudne; prezentuje to ten oto skrypt:
  5. [csharp]# pokemonize.ps1
  6. # Zmienia litery w tekście na losowo duże lub małe
  7.  
  8. begin
  9. {
  10.     # Inicjujemy generator liczb losowych
  11.     $rand = New-Object Random
  12. }
  13.  
  14. process
  15. {
  16.     $str = $_.ToString()
  17.     $result = New-Object Text.StringBuilder
  18.    
  19.     # Zmieniamy znaki
  20.     for ($i = 0; $i -lt $str.Length; ++$i)
  21.     {
  22.         if ($rand.NextDouble() -lt [float]0.5)
  23.             { $newChar = [Char]::ToLower($str[$i]) }
  24.         else
  25.             { $newChar = [Char]::ToUpper($str[$i]) }
  26.            
  27.         $result.Append($newChar) | Out-Null
  28.     }
  29.    
  30.     # Wyświetlamy przetworzony ciąg
  31.     $result.ToString()
  32. }[/csharp]
  33. Tym, co on robi, jest losowa zmiana wielkości liter w ciągu stanowiącym tekstową reprezentację obiektu (lub obiektów), jaki dostaje na wejściu. Jednym słowem, dokonuje jego <em>pokemonizacji</em>... Pewnie dla niektórych byłoby to przydatne, ale powiedzmy, że to tylko taki przykład ;P
  34. Najważniejsze jest to, że podany skrypt działa dobrze na obiektach otrzymanych poprzez potok, czyli np. linijkach tekstu odczytanego z pliku poprzez <kbd>Get-Content</kbd>:
  35. [code]Get-Content ./Plik.txt | . ./pokemonize.ps1 | Out-Host

Dla każdego takiego obiektu (tutaj: wiersza z pliku) wykonywany jest blok process, w którym to ów obiekt jest reprezentowany jako zmienna $_. Można to sobie wyobrazić jako wnętrze pętli foreach, przelatującej po wszystkich obiektach z wejścia skrypt. Dodatkowo możemy jeszcze określić bloki: begin (uruchamiany na samym początku) i end (na końcu). W nich powinniśmy umieścić ewentualny kod inicjalizujący i/lub kończący pracę skryptu.

Tags: ,
Author: Xion, posted under Applications »



Adding comments is disabled.

Comments are disabled.
 


© 2019 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.