比較演算子

PowerShell Coreの比較演算子は、現在主流のプログラミング言語と比べるとかなり特徴的だ。

例えば、現在メジャーなプログラミング言語では「>」は「大なり」を意味する比較演算子になるのだが、PowerShell Coreでは「>」はリダイレクトを意味しており、比較演算子としては扱われていない。

PowerShell Coreの比較演算子はハイフンからはじめるようになっており、単語または単語の頭文字が使われている。「大なり」を意味するのは「>」ではなく「-gt」だ。gtというのはgreater thanという英語の単語の頭文字をくっつけたもので、要するに英語で「大なり」を短縮表示したものが「gt」であり、「-gt」が大なりとして使われている。

次の表をみるとわかりやすいと思う。PowerShell Coreで使われている比較演算子は次のとおり。

比較演算子 内容
-eq 等しい
-ne 等しくない
-gt 大なり
-ge 大なりまたは等しい
-lt 小なり
-le 小なりまたは等しい
-like ワイルドカードパターンに一致した文字列の場合に真
-notlike ワイルドカードパターンに一致しなかった文字列の場合に真
-match 正規表現に文字列が一致した場合に真
-notmatch 正規表現に文字列が一致しなかった場合に真
-contains 参照値がコレクションに含まれている場合に真
-notcontains 参照値がコレクションに含まれていない場合に真
-in テスト値がコレクションに含まれている場合に真
-notin テスト値がコレクションに含まれていない場合に真
-replace 文字列パターンを入れ替え
-is オブジェクトの双方の型が等しい場合に真
-isnot オブジェクトの双方の型が等しくない場合に真

ハイフンからはじまる文字列を比較演算子として使用するプログラミング言語としては、シェルなどが該当する。Bourne Shell系のシェルスクリプトではtest(1)というコマンドで比較演算子を処理することが多いのだが、このコマンドはハイフンからはじまる文字列を比較演算子として処理する。PowerShell Coreもこれと同じようにハイフンからはじまる文字列を比較演算子として使っている。

また、PowerShell Coreの比較演算子は配列を比較対象とすることができ、その場合の評価結果はTrueやFalseではなく、値を返すといった動作になる。文字列と配列を比較するといった処理が可能で、このあたりの動作はPowerShell Coreに特徴的なものだ。

なお、ここでひとつ、大文字と小文字について注意する必要がある。PowerShell Coreの比較演算子はデフォルトでは大文字と小文字を区別しない設定になっている。

例えば、等号を意味する-eqはデフォルトでは大文字と小文字を区別しない。大文字と小文字を区別させたい場合には、ハイフンと比較演算子の文字列の間にcを挟んで-ceqのように記述する。逆に、明示的に大文字と小文字を区別しないよう指定する場合には、ハイフンと比較演算子の文字列の間にiを挟んで-ieqのように記述する。

等号、不等号、大なり、小なり

PowerShell Coreで等号、不等号、大なり、小なりといった比較演算子を使ったサンプルの実行例を次に示す。

等号の実行サンプル

PS /Users/daichi> 2 -eq 2
True
PS /Users/daichi> 2 -eq 3
False
PS /Users/daichi> 1,2,3 -eq 2
2
PS /Users/daichi> "abc" -eq "abc"
True
PS /Users/daichi> "abc" -eq "ABC"
True
PS /Users/daichi> "abc" -eq "abc", "def"
False
PS /Users/daichi> "abc", "def" -eq "abc"
abc
PS /Users/daichi> "abc", "def" -eq "ABC"
abc
PS /Users/daichi> "abc", "def" -ieq "ABC"
abc
PS /Users/daichi> "abc" -ceq "ABC"
False
PS /Users/daichi> "abc" -ieq "ABC"
True
PS /Users/daichi>

等号の実行サンプルとしては、「文字列 -eq 配列」ではFalseになる比較が、「配列 -eq 文字列」の比較になる場合には一致する文字列が結果として返ってきているところなどに注目しておきたい。PowerShell Coreではこうした等号の使い方ができる。

また、-ceqで大文字と小文字と区別した比較、-ieqで大文字と小文字を区別しない比較が行われている点にも注目しておきたい。これは不等号-neにおいても同様だ。

不等号の実行サンプル

PS /Users/daichi> "abc" -ne "def"
True
PS /Users/daichi> "abc" -ne "abc"
False
PS /Users/daichi> "abc" -ne "ABC"
False
PS /Users/daichi> "abc" -cne "ABC"
True
PS /Users/daichi> "abc" -ine "ABC"
False
PS /Users/daichi>

大なりや大なりイコールでも配列を使うことが可能で、「配列 -gt 数値」といった比較を行った場合、該当する値の配列が戻ってくる。

大なり、大なりイコールの実行サンプル 

PS /Users/daichi> 8 -gt 6
True
PS /Users/daichi> 7, 8, 9 -gt 8
9
PS /Users/daichi> 8 -ge 8
True
PS /Users/daichi> 7, 8, 9 -ge 8
8
9
PS /Users/daichi>

小なり、小なりイコールの実行サンプル

PS /Users/daichi> 8 -lt 6
False
PS /Users/daichi> 7, 8, 9 -lt 8
7
PS /Users/daichi> 6 -le 8
True
PS /Users/daichi> 7, 8, 9 -le 8
7
8
PS /Users/daichi>

上記のように小なりおよび小なりイコールに関しても同様だ。

-like、-notlike

文字列をワイルドカード含めてマッチングさせる処理には-likeまたは-nolikeが便利だ。次のように使用できる。

-like、-notlikeの実行サンプル

PS /Users/daichi> "PowerShell" -like "*shell"
True
PS /Users/daichi> "PowerShell", "Server" -like "*shell"
PowerShell
PS /Users/daichi> "PowerShell" -notlike "*shell"
False
PS /Users/daichi> "PowerShell", "Server" -notlike "*shell"
Server
PS /Users/daichi>

-likeや-notlikeにおいても比較に配列を含めることができ、「配列 -like 文字列」のような比較で実行すると該当するデータが配列で返ってくる。

-match、-notmatch

-likeや-notlikeはワイルドカードを含めて一致比較を実施するが、指定した文字列が含まれているかどうかは-matchまたは-notmatchを使って調べることになる。動作としては文字列の前後にワイルドカードを指定したような感じを想像するとわかりやすい。

-matchの実行サンプル

PS /Users/daichi> "Sunday", "Monday", "Tuesday" -match "sun"
Sunday
PS /Users/daichi> $Matches
PS /Users/daichi> "Sunday" -match "sun"
True
PS /Users/daichi> $Matches

Name                           Value
----                           -----
0                              Sun

PS /Users/daichi> "Banana" -match "na"
True
PS /Users/daichi> $Matches

Name                           Value
----                           -----
0                              na

PS /Users/daichi>

-notmatchの実行サンプル

PS /Users/daichi> "Sunday" -notmatch "rain"
True
PS /Users/daichi> $Matches
PS /Users/daichi> "Sunday" -notmatch "day"
False
PS /Users/daichi> $Matches

Name                           Value
----                           -----
0                              day

PS /Users/daichi> "Sunday" -notmatch "sun"
False
PS /Users/daichi> $Matches

Name                           Value
----                           -----
0                              Sun

PS /Users/daichi> "Sunday", "Monday" -notmatch "sun"
Monday
PS /Users/daichi>

-matchでも-notmatchでも一致したものは$Matchesという変数に格納される仕組みになっている。-matchと-notmatchでは条件が逆になっているのだが、$Matchesには一致した結果が格納されている。

-contains

-matchや-notmatchに似ているが文字列の前後にワイルドカードを含まないイメージというか、対象となる文字列が含まれている場合に真となるのが-contains、その逆が-notcontainsとなる。

-containsの実行サンプル

PS /Users/daichi> "abc", "def" -contains "def"
True
PS /Users/daichi> "Windows", "PowerShell" -contains "Shell"
False
PS /Users/daichi> "abc", "def", "ghi" -contains "abc", "def"
False
PS /Users/daichi> $a = "abc", "def"
PS /Users/daichi> "abc", "def", "ghi" -contains $a
False
PS /Users/daichi> $a, "ghi" -contains $a
True
PS /Users/daichi>

-in、-notin

-containsや-notcontainsと指定の順序が逆になるのが-inと-notinだ。

-inの実行サンプル

PS /Users/daichi> "def" -in "abc", "def"
True
PS /Users/daichi> "Shell" -in "Windows", "PowerShell"
False
PS /Users/daichi> "Windows" -in "Windows", "PowerShell"
True
PS /Users/daichi> "Windows", "PowerShell" -in "Windows", "PowerShell", "ServerManager"
False
PS /Users/daichi> $a = "Windows", "PowerShell"
PS /Users/daichi> $a -in $a, "ServerManager"
True
PS /Users/daichi>

-notinの実行サンプル

PS /Users/daichi> "def" -notin "abc", "def"
False
PS /Users/daichi> "ghi" -notin "abc", "def"
True
PS /Users/daichi> "Shell" -notin "Windows", "PowerShell"
True
PS /Users/daichi> "Windows" -notin "Windows", "PowerShell"
False
PS /Users/daichi>

PowerShell Coreはこのあたりの引数指定の順序が英語のシンタックスをそのままもってきたような仕組みになっている。賛否両論あるように思うが、こういうものだと飲み込んでおいた方がよいだろう。

-replace

文字列の一部の文字を別の文字に置き換えるのが-replaceとなる。

-replaceの実行サンプル

PS /Users/daichi> "book" -replace "B", "C"
Cook
PS /Users/daichi> "book" -ireplace "B", "C"
Cook
PS /Users/daichi> "book" -creplace "B", "C"
book
PS /Users/daichi>

-replaceにおいてもデフォルトでは大文字と小文字は無視して一致処理が行われるので、大文字と小文字を区別したいときには-creplaceとcを指定した処理を行う。

-is、-isnot

型の比較は-isおよび-isnotだ。-notisではないのは、やはり英語のシンタックスをそのまま言語仕様に落とし込んだためだろう。これはこういうものだと割り切るしかない。

PS /Users/daichi> $a = 1
PS /Users/daichi> $b = "1"
PS /Users/daichi> $a -is [int]
True
PS /Users/daichi> $a -is $b.GetType()
False
PS /Users/daichi> $a -isnot $b.GetType()
True
PS /Users/daichi> $b -isnot [int]
True
PS /Users/daichi>

このように多少違和感を覚えなくもないネーミングになっているのだが、PowerShell Coreの比較演算子は機能としては強力だ。PowerShell Coreを使ってスクリプトを書くうえで必要になるので、ぜひ覚えてしまおう。

参考資料