PowerShell スクリプトでパイプラインを使用するスクリプトおよび、関数の記載方法の覚書を記載します。

1. パイプラインを使用するサンプル

パイプラインを使用するスクリプトは、begin, process, end セクションを使用して記述します。 begin セクションに初期化、process セクションにパイプライン処理、 end セクションに終了を記載します。パイプラインを解して渡される値には $_ か $input でアクセスします。

簡単ですが、Get-Content で取得したテキストの内容から、特定のパターンを含む行数を出力する Select-Count.ps1 というスクリプト作成しました。

# Select-Count.ps1
 param([string] $pattern = $(throw "検索パターンを指定してください"))
  
  # 初期化
  begin{
    $count = 0
  }
  # パイプライン処理
  process{
    if($_ -match $pattern){ $count++ }
  }
  end{
    $count
  }

次のように実行します。

PS E:\scripts> Get-Content ex090918.log | .\Select-Count  "\.aspx"
8442

関数で定義する場合は、次のようになります。

function Select-Count([string] $pattern = $(throw "検索パターンを指定してください")){
  # 初期化
  begin{
    $count = 0
  }
  # パイプライン処理
  process{
    if($_ -match $pattern){ $count++ }
    # 列挙子 $input を使用してパイプライン入力にアクセスできる
    #if($input -match $pattern) { $count++}
  }
  end{
    $count
  }
}

2. すべてのパイプライン入力を受け取るには

パイプラインの入力全体にアクセスする必要がある場合など、パイプライン入力をすべて受け取ってから戻り値を作成したい場合があります。$input をリスト評価構文 @() を適用することで、パイプライン入力をすべて配列として受け取ることができます。この場合、後続へのパイプライン処理は一旦終了し、関数がすべて処理を終了した後の返り値を使用して新たにパイプライン処理が行われることになります。

# パイプラインからの入力をパイプライン処理せずに一気に取得する場合
function Select-CountNoPipline([string] $pattern = $(throw "検索パターンを指定してください")){
   $count = 0
   # 後続の処理にパイプライン処理をストリーミングせずに、
   # いったんすべてのパイプライン入力を受け取る方法
  $inputs = @($input)
   foreach($line in $inputs){
     if($line -match $pattern){ $count++ }
   }
   
   $count
}

3. まとめ

パイプライン処理をする方法を覚書として記載しました。間違い、指摘点などありましたらご連絡ください。