はじめに
初投稿です。
さっそく本題ですが、Powershell を触っていく内に以下のようなコードと遭遇することがあると思います。
Get-Process | Where-Object { $_.CPU -gt 100 }
えっ何これは、、、😅
- コマンドとコマンドの間に挟まる謎の「|(ASCII 124) 」
- 定義してもないのに突然出てくる「$_」変数
「お前は誰だよ」と言いたくなりますが、
ま、ま、そう、焦んないで。
この記事では コマンドや関数の話はいったん脇に置いて、
配列のような 生の値 から Powershell のパイプラインを理解していきます🫵
パイプラインは「値が流れる道」
まずは、以下のような簡単な配列を用意します。
1..10
これは 範囲演算子 といって、1から10までの整数配列を生成しています。
では、パイプラインを繋げてみましょう。
1..10 | ForEach-Object { Write-Host "$_ が流れている" }
ここでは、ForEach-Object というコマンドをパイプラインに繋げています。
このコマンドは「|」の左側の値に対して、{}内に書かれた処理を行います。
実際に実行結果を見てみると…
- 1 が流れている
- 2 が流れている
- 3 が流れている
- …
というように、「|」を跨いで、変数「$_」に値が1個ずつ流れていることが分かります。
$_ の正体
ここまでで、なんとなく
- 「
$_に値が入ってる」 - 「でもどこから来たのか分からない」
という状態だと思います。
結論から言うと、
$_は「今パイプラインを流れてきた値」
です。
さっきのコードをもう一度見てみましょう。
1..10 | ForEach-Object {
Write-Host "$_ が流れている"
}
これは、内部的には次の foreach とほぼ同じことをしています。
foreach ($n in 1..10) {
Write-Host "$n が流れている"
}
対応関係を書くと、こうです。
| パイプライン | foreach |
|---|---|
$_ |
$n |
| ForEach-Object | 繰り返し処理 |
つまり、
-
foreachでは$n - パイプラインでは $_
という名前で「今の値」を受け取っているのです!
Where-Object で絞り込む
では次に、よく見るこの形に進みます。
1..10 | Where-Object { $_ -gt 5 }
これは、
- 1〜10 の中から
- 5 より大きいものだけを残す
という処理です。
これも foreach に書き直すと、こうなります。
foreach ($n in 1..10) {
if ($n -gt 5) {
$n
}
}
Where-Object は、
- パイプラインで値を受け取り
- 条件に合うものだけを
- 次に流す
という役割を持っています。
👉 Where-Objectは「暗黙の foreach + if」
こう考えると、一気に読みやすくなります。
数値だけじゃない。文字列も流せる
ここまで数値を使ってきましたが、
パイプラインは数値専用ではありません。
"apple", "banana", "cherry" |
ForEach-Object {
Write-Host "$_ が流れている"
}
この場合、流れているのは
- "apple"
- "banana"
- "cherry"
という 文字列 です。
もちろん、Where-Object も使えます。
"apple", "banana", "cherry" |
Where-Object { $_ -like "a*" }
実は、今まで全部「オブジェクト」
ここで一つだけ、重要な話をします。
"apple".GetType().Name
1.GetType().Name
どちらも「型」を持っています。
つまり、
- 数値
- 文字列
これらはすべて オブジェクト です。
PowerShell のパイプラインでは、
オブジェクトが、そのままの形で流れる
というのが最大の特徴です。
オブジェクトを作って流してみる
最後に、少しだけ PowerShell らしいことをしてみます。
1..3 | ForEach-Object {
[pscustomobject]@{
Number = $_
Square = $_ * $_
}
}
ここでは、
- Number(元の値)
- Square(二乗した値)
を持つオブジェクトを作っています。
さらにパイプラインをつなげると、
1..3 |
ForEach-Object {
[pscustomobject]@{
Number = $_
Square = $_ * $_
}
} |
Where-Object { $_.Square -gt 4 }
今パイプラインを流れているのは、
- 数値でも
- 文字列でもなく
「Number と Square を持つオブジェクト」 です。
👉 形のあるデータが、そのまま次へ流れる
これが PowerShell のパイプラインの強さです。
まとめ
- 値(オブジェクト)を 1個ずつ 流す仕組み
-
$_は「今流れてきたオブジェクト」 - 始点は
1..10のような生の値でもいい
最後に
パイプラインはPowershellにおいて重要な要素です。
この記事だけでは、そのすべてを伝えきることはまったくできていません。
勉強の中で躓くところも多く出ると思いますが、覚えるとPowershellが、
より一層楽しく使えるようになるので、ぜひ覚えてみてください。