【PowerShell】比較演算子と条件分岐(if/switch)|-eq・-like・-match の使い分け

【PowerShell】比較演算子と条件分岐(if/switch)|-eq・-like・-match の使い分け PowerShell

PowerShellで「もし〜なら」という条件分岐を書くとき、つまずきやすいのが比較演算子です。他の多くの言語では==>を使いますが、PowerShellでは-eq-gtのようにハイフン付きの演算子を使います。==は使えません。

さらに、PowerShell特有の落とし穴があります。文字列の比較が既定で大文字小文字を区別しないこと、そして配列に-eqを使うと判定ではなくフィルタになることです。これらを知らないと、条件が思ったとおりに動きません。この記事では、実機で確認しながら、比較演算子とifswitchを確実に使えるように整理します。

先に結論

  • 比較は-eq(等しい)・-ne(等しくない)・-gt(より大きい)などを使います。==は使えません。
  • =は代入、-eqは比較です。if ($x = 5)は代入になってしまうので注意します。
  • 文字列の比較は既定で大文字小文字を区別しません。区別するなら-ceqなどを使います。
  • -likeはワイルドカード(*)、-matchは正規表現です。用途で使い分けます。
  • 配列に-eqを使うと、一致した要素を返すフィルタになります。判定には-contains-inを使います。
  • 複数分岐はswitchが便利ですが、breakがないと一致した節がすべて実行されます。

条件による絞り込みは条件一致したデータだけを抽出する方法、配列の扱いは配列とハッシュテーブルの使い方-matchの詳細は正規表現で検索・置換する方法もあわせて参考になります。

スポンサーリンク

比較演算子の一覧

よく使う比較演算子をまとめます。すべてハイフンで始まり、文字列に使う場合は既定で大文字小文字を区別しません。

演算子 意味 例(結果)
-eq 等しい 5 -eq 5(True)
-ne 等しくない 5 -ne 3(True)
-gt より大きい 5 -gt 3(True)
-ge 以上 5 -ge 5(True)
-lt より小さい 3 -lt 5(True)
-le 以下 3 -le 3(True)
-like ワイルドカード一致 "a.txt" -like "*.txt"(True)
-match 正規表現一致 "abc123" -match "\d+"(True)
-contains 配列が値を含む 1,2,3 -contains 2(True)
-in 値が配列に含まれる 2 -in 1,2,3(True)

if / elseif / else の基本

条件分岐の基本はifです。条件には先ほどの比較演算子を使います。複数の条件を順に試すならelseif、どれにも当てはまらない場合はelseを使います。

if-else.ps1
$score = 75

if ($score -ge 80) {
    Write-Host "合格(優)"
}
elseif ($score -ge 60) {
    Write-Host "合格"
}
else {
    Write-Host "不合格"
}

条件式は丸かっこ( )で囲み、処理は波かっこ{ }で囲みます。elseifはいくつでも並べられます。

【重要】=は代入、-eqが比較

最初にやりがちな間違いが、比較のつもりで=を使うことです。=代入であり、比較ではありません。比較は必ず-eqを使います。

assign-vs-compare.ps1
$x = 5

# NG: = は代入。$x に 3 を入れてしまう(比較にならない)
# if ($x = 3) { ... }

# OK: -eq が比較
if ($x -eq 5) {
    Write-Host "x は 5 です"
}

# 大小比較も同様
if ($x -gt 3) {
    Write-Host "x は 3 より大きい"
}

多くの言語の==に当たるのが-eq>に当たるのが-gtです。記号の比較演算子はPowerShellでは使えないため、必ずハイフン付きを使ってください。

文字列比較は既定で大文字小文字を区別しない

PowerShellの比較演算子は、文字列に対して既定で大文字小文字を区別しません。多くの言語と逆の挙動なので注意が必要です。区別したいときは、頭にcを付けた-ceqなどを使います。

case-sensitivity.ps1
# 既定では大文字小文字を区別しない
"ABC" -eq "abc"     # True(一致する)
"Yes" -eq "yes"     # True

# -ceq で区別する(c = case-sensitive)
"ABC" -ceq "abc"    # False

# 入力チェックでは、この既定の挙動が役立つことも多い
$answer = "YES"
if ($answer -eq "yes") {
    Write-Host "はいと判定(大文字小文字を問わない)"
}

実機でも、"ABC" -eq "abc"True-ceqではFalseになりました。利用者の入力(はい/ハイ/YES など)を判定するときは、区別しない既定が便利です。逆に、パスワードのように区別が必要な場面では-ceqを使います。

-like(ワイルドカード)と-match(正規表現)の使い分け

部分一致やパターン一致には-like-matchがあります。両者はパターンの書き方が異なり、混同しやすいので使い分けを押さえます。

like-vs-match.ps1
# -like はワイルドカード(* は任意の文字列、? は任意の1文字)
"report.txt"  -like "*.txt"     # True
"image01.png" -like "image??.*" # True

# -match は正規表現
"abc123" -match "\d+"           # True(数字を含む)
"2026-03" -match "^\d{4}-\d{2}$" # True

# 用途の目安
# ・ファイル名や単純な前方/後方一致 → -like
# ・桁数や複雑なパターンの抽出 → -match

ざっくり言うと、*?で済む単純な一致は-like、桁数の指定やグループ抽出が必要な複雑なパターンは-matchです。-matchの詳しい使い方は正規表現で検索・置換する方法で解説しています。

配列の判定 -contains / -in

「ある値が配列に含まれているか」を判定するには-containsまたは-inを使います。2つは判定の向きが逆なだけで、結果は同じです。

contains-in.ps1
$fruits = @("りんご", "みかん", "ぶどう")

# 配列 -contains 値
$fruits -contains "みかん"   # True

# 値 -in 配列(向きが逆)
"みかん" -in $fruits         # True

# 否定
$fruits -notcontains "もも"  # True

# if と組み合わせる
if ($fruits -contains "りんご") {
    Write-Host "りんごがあります"
}

【最重要】配列に-eqを使うとフィルタになる

ここがPowerShellで最も意外な挙動です。-eqの左に配列を置くと、結果は$true$falseではなく、一致した要素だけを集めた配列になります。判定のつもりで使うと、思わぬ動きになります。

array-eq-filter.ps1
$nums = @(1, 2, 3, 2, 1)

# 配列 -eq は「一致した要素を返すフィルタ」
$nums -eq 2          # 2, 2 ← bool ではなく要素の配列
($nums -eq 2).Count  # 2(2 が何個あるか)

# 含まれるかを「判定」したいなら -contains を使う
$nums -contains 2    # True

# null 判定は $null を左に置くのが定石
$value = @()
$null -eq $value     # 正しく判定できる
# $value -eq $null は配列だと空が返り、判定が崩れる
含まれるかの判定は -contains / -in を使う

実機で確認したところ、@(1,2,3,2,1) -eq 22, 2という配列(型はObject[])を返しました。ifの条件に置くと、一致が0件なら空配列で「偽」、1件以上なら「真」と評価されるため、たまたま動くこともありますが本来の使い方ではありません。「含まれるか」を判定したいときは-contains-inを使ってください。なお、この性質は値の絞り込みには便利で、$nums -eq 2で一致要素を取り出す用途には使えます。

論理演算子で条件を組み合わせる

複数の条件を組み合わせるには、-and(かつ)・-or(または)・-not(否定、!でも可)を使います。

logical-operators.ps1
$age = 25
$hasTicket = $true

# -and:両方が真
if ($age -ge 20 -and $hasTicket) {
    Write-Host "入場できます"
}

# -or:どちらかが真
if ($age -lt 13 -or $age -ge 65) {
    Write-Host "割引対象です"
}

# -not(! でも同じ)
if (-not $hasTicket) {
    Write-Host "チケットがありません"
}

実機でも、(5 -gt 3) -and (2 -lt 1)False-not $falseTrueになりました。条件が複雑になるときは、丸かっこで囲んで優先順位を明確にすると読みやすくなります。

真偽値(偽として扱われるもの)

ifの条件には、比較式だけでなく値そのものも書けます。次の値は「偽」として扱われ、それ以外は「真」になります。

truthiness.ps1
[bool]0       # False(数値の 0)
[bool]""      # False(空文字列)
[bool]$null   # False
[bool]@()     # False(空配列)

[bool]"abc"   # True
[bool]1       # True
[bool]@(1, 2) # True(要素のある配列)

# 配列に要素があるかの判定(最も確実なのは .Count)
$items = Get-ChildItem "C:\work"
if ($items.Count -gt 0) {
    Write-Host "ファイルがあります"
}

0・空文字列・$null・空配列が「偽」になります。なお、要素が1個だけの配列はその要素で判定されるため(@(0)は偽)、配列に要素があるかを確実に判定したいときは.Count -gt 0を使うのが安全です。

switchで複数分岐を書く(フォールスルーに注意)

分岐が3つ4つと増えると、ifelseifの連続は読みにくくなります。値によって分けるならswitchがすっきりします。ただし、PowerShellのswitchには独特の注意点があります。

switch-basic.ps1
$day = 3

switch ($day) {
    1 { "月曜" }
    2 { "火曜" }
    3 { "水曜" }
    default { "その他" }
}
# 水曜

# 注意: break がないと、一致した節がすべて実行される
switch (2) {
    2 { "two" }
    2 { "two-again" }   # ここも実行されてしまう
}
# two / two-again の両方が出る

# break で1つ目だけにする
switch (2) {
    2 { "two"; break }
    2 { "two-again" }
}
# two だけ
switchは一致した節をすべて実行する

多くの言語のswitchは、一致した分岐を実行すると自動で抜けます。しかしPowerShellのswitchは、一致するすべての節を上から実行します。実機でも、switch (2)2の節が2つあると両方が実行されました。1つだけ実行して抜けたい場合は、節の最後にbreakを書いてください。

switch -Wildcard / -Regex で柔軟に分岐する

switchはオプションを付けると、ワイルドカードや正規表現で分岐できます。文字列のパターンによる分岐に便利です。

switch-wildcard-regex.ps1
# -Wildcard:* や ? で分岐
switch -Wildcard ("file.log") {
    "*.txt" { "テキストファイル" }
    "*.log" { "ログファイル" }
    default { "その他" }
}
# ログファイル

# -Regex:正規表現で分岐。$Matches も使える
switch -Regex ("order-123") {
    "^order-(\d+)$" { "注文番号: " + $Matches[1] }
    "^user-(\d+)$"  { "ユーザー番号: " + $Matches[1] }
}
# 注文番号: 123

実機でも、switch -Wildcard"file.log""*.log"に一致し、switch -Regexでは$Matches[1]から123を取り出せました。条件が文字列パターンのときは、ifを並べるよりswitch -Regexのほうが見通しよく書けます。

よくある失敗

比較に==や>を使ってエラーになる

PowerShellでは記号の比較演算子は使えません。-eq-gtなどハイフン付きを使います。

比較のつもりで=を書いて代入になる

if ($x = 5)$x5を代入してしまいます。比較は-eqです。

大文字小文字が区別されると思い込む

文字列比較は既定で区別しません。区別が必要なら-ceqなどを使います。

配列の判定に-eqを使う

配列に-eqを使うとフィルタになり、判定にはなりません。含まれるかの判定は-contains-inを使います。

switchでbreakを忘れて複数の節が動く

PowerShellのswitchは一致した節をすべて実行します。1つで止めたいならbreakを書きます。

よくある質問

Qなぜ == や > が使えないのですか?
APowerShellでは、比較に-eq-gtのようなハイフン付きの演算子を使う仕様だからです。>はリダイレクト(ファイルへの出力)の意味を持つため、比較には使えません。記号ではなくハイフン付きを覚えてください。
Q-contains と -eq はどう違いますか?
A-containsは「配列が値を含むか」を$true$falseで判定します。一方、配列に-eqを使うと、一致した要素を返すフィルタになります。含まれるかの判定には-contains-inを使ってください。
Q-like と -match のどちらを使えばいいですか?
A*?で表せる単純な一致なら-like、桁数指定やグループ抽出などの複雑なパターンなら-match(正規表現)です。ファイル名の判別などは-likeが手軽です。
Qswitchとif-elseifはどちらを使うべきですか?
A1つの値を複数の候補と比べるならswitchが読みやすく、範囲や複数条件の組み合わせならifelseifが向いています。文字列パターンで分けるならswitch -Regexも便利です。
Qnull かどうかを判定するには?
A$null -eq $valueのように、$nullを左に置くのが定石です。$valueが配列のとき、$value -eq $nullと書くと判定が崩れることがあるためです。

まとめ

  • 比較は-eq-gtなどハイフン付きを使います。==>は使えません。
  • =は代入、-eqは比較です。混同に注意します。
  • 文字列比較は既定で大文字小文字を区別しません。区別するなら-ceqです。
  • -likeはワイルドカード、-matchは正規表現。含まれるかの判定は-contains-inです。
  • 配列に-eqを使うとフィルタになります。判定と取り違えないようにします。
  • switchは一致した節をすべて実行するため、必要に応じてbreakを書きます。

PowerShellの条件分岐は、「比較はハイフン付き」「文字列は大小を区別しない」「配列の-eqはフィルタ」という3点さえ押さえれば、つまずきません。ifswitchを使い分けて、読みやすい分岐を書けるようになります。