- パイプラインの基本
- パイプライン変数
$_ が要素一つ一つ。
PS> @(1,2,3) | % { $_; } 1 2 3
- 列挙
% {} で表現。{} 内に列挙時の処理を書く。
% は ForEach-Object の Alias。Foreach とも書ける。PS > @(1..5) | % { $_ * 100; } 100 200 300 400 500
- 列挙 その2
パイプラインの始端,または終端で、初期処理,あるいは終了処理がしたい場合は、% (ForEach) ではなく & (スクリプトブロックの実行)を用いる。
begin {} の中に、初期処理を、
process {} の中に、ForEach などで書いていた、パイプラインのコレクションごとの処理を、
end {} の中に、終了処理を書く。PS > @(1..3) | &{ >> begin { "初期処理"; } >> process { $_ * 200; } >> end { "終了処理"; } >> } 初期処理 200 400 600 終了処理
- フィルタリング
? {} で表現。{} 内にフィルター条件の処理を書く。
? は Where-Object の Alias。Where とも書ける。
処理の結果、0 (= $False),$null,結果がない、などの場合は、入力されたオブジェクトは次のパイプラインに渡さない。PS > @(1..5) | ? { $_ % 2; } 1 3 5
- パイプライン変数
- パイプラインへの出力
パイプラインへ出力は、直接その値を記述することで行う。
- リテラルをパイプラインに出力
PS> "AAA" | % { $_; } AAA
- 出力先の指定がない場合の出力先
最終出力先(変数代入やファイルへの出力)の指定が場合、パイプライン出力はコンソールに渡される。
PS> @(1,2,3) | % { $_; } # この文の実行でデータが表示される 1 2 3
- 出力先を変数にした場合
変数への代入するとコンソールに出力されずに、その内容が変数に格納される。
PS> $a = @(1,2,3) | % { $_; } # この文の実行ではデータは表示されない PS> $a.Count #件数 3 PS> $a #内容 1 2 3
- 複数の値を出力した場合
それぞれがパイプラインへ出力される。
PS> $a = @(1,2,3) | % { "****"; $_; $_; } PS> $a.Count 9 PS> $a **** 1 1 **** 2 2 **** 3 3
- 次のパイプラインに出力を渡さない
パイプラインへは出力されない場合。
PS> $a = @(1,2,3) | % { } PS> $a.Count 0
Write-Host の出力は パイプラインに出力されない。
PS> $a = @(1,2,3) | % { Write-Host $_; } 1 2 3 PS> $a.Count 0
パイプラインでつないだ場合、処理の実行順が一般的な言語とは異なる点に注意。
パイプラインに出力するたびに、パイプラインの先の処理に制御が移る。
パイプラインに渡す前までの処理をすべてやりきって、その結果をまとめて次のパイプラインに渡すわけではない。
一般的の言語の場合だと、コルーチン(yeild) を使った動きに似ている。(*1)
PS > @("A","B","C") | >> % { Write-Host "1st :$_"; $_ + "*"; } | >> % { Write-Host "2nd :$_"; $_ + "#"; } | >> % { Write-Host "3rd :$_"; } >> 1st :A 2nd :A* 3rd :A*# 1st :B 2nd :B* 3rd :B*# 1st :C 2nd :C* 3rd :C*#
括弧で囲むと、そこまでの処理が確定される。
PS > ( >> @("A","B","C") | >> % { Write-Host "1st :$_"; $_ + "*"; } | >> % { Write-Host "2nd :$_"; $_ + "#"; } >> ) | >> % { Write-Host "3rd :$_"; } >> 1st :A 2nd :A* 1st :B 2nd :B* 1st :C 2nd :C* 3rd :A*# 3rd :B*# 3rd :C*#
(*1) VB で同様の動きをさせようとすると、以下のようなコードで実現できる。
Module Module1 Sub Main() Third( Second( First( {"A", "B", "C"} ) ) ). ToArray() End Sub Iterator Function First(input As IEnumerable(Of String)) As IEnumerable(Of String) For Each s In input Console.WriteLine("1st :" & s) Yield s & "*" Next End Function Iterator Function Second(input As IEnumerable(Of String)) As IEnumerable(Of String) For Each s In input Console.WriteLine("2nd :" & s) Yield s & "#" Next End Function Iterator Function Third(input As IEnumerable(Of String)) As IEnumerable(Of String) For Each s In input Console.WriteLine("3rd :" & s) Yield s Next End Function End Module
結果
1st :A 2nd :A* 3rd :A*# 1st :B 2nd :B* 3rd :B*# 1st :C 2nd :C* 3rd :C*#