PowerShellの演算

たいていのプログラミング言語入門では、このタイミングで演算についての話題に触れることが多い。PowerShellでももちろん演算ができる。加算については前の章でしれっと登場してしまっている。

PowerShellにおいて演算子と呼ばれるものはそこそこ多く、bashのようなシェルスクリプトを意識していることがわかる。演算子は計算を行うための算術演算子、条件に合致するかを確認する比較演算子などが存在している。算術演算子については割り算の余りを計算する「%」がVBAから入門してきた方には目新しい程度であり、驚くようなことはあまりないだろう。

仲間と言ってはいけないかもしれないが、文字列の結合を行うのも「+」演算子である。ここはVBAとは異なり「&」を使用することはできない。なぜなら、「&」記号には演算子としてほかの役割があるためだ。後述する。

算術演算子

「+」は加算、「-」は減算、「*」は乗算、「/」は除算である。これに加えて余りを計算する「%」がある程度で、目新しくもなんともない。ビット演算を行うこともできるが、PowerShellの用途としてはあまり考えにくいところではある。

# 左へ2ビットだけシフトする
1 -shl 2  # => 4

# 右へ3ビットだけシフトする
8 -shr 3 # => 1

結合演算子

上述しているが、「+」で文字列同士を結合することができる。また、「*」を利用すると指定回数だけ繰り返した文字列をつくることができる。これもまたあまり使い道がないかもしれない。せいぜい半角スペースを指定回数だけつめるなどのケースくらいだろう。

"abc" * 3  # => abcabcabc

なお、結合できるのは文字列だけではない。配列についても結合することができる。「+」「*」のいずれも利用することができる。

比較演算子

PowerShellでは比較演算子が一番多く、かつ不思議な動きをすることが多いことでも知られている。便利な機能を持つものもあるのでぜひ色々と試してみていただきたい。

一致していることを確認するには「-eq」を利用する。これは演算子の右と左がともに配列でない場合の動作だ。

1 -eq 2  # => False

変数が存在しているかのチェックとしてnullかどうかをチェックすることが多いが、そうしたときには注意が必要である。

$aaa -eq $null

PowerShellにおけるnullの表現は特殊変数「$null」を利用する。上記のコードでは変数aaaがnullに一致するかをチェックしているはずだ。ただし、これが考えている通りの動作をするのは変数aaaが配列でないときだけだ。この比較演算子「-eq」は演算子の左側が配列である場合には自動的に右側にきた値に合致する要素を配列で返す演算子に変化する。極端な例を示すと次のようになる。

$a = @(1, $null, 2, $null)
$b = $a -eq $null

上記の例の場合、$aがnullかどうかをチェックしているはずなので変数bには真偽値であるTrueかFalseが入っていることが期待される。しかし実際のところ変数bはTrueにもFalseにもならない。それは変数bが配列になっているためだ。上記の例では$nullに合致する要素が取り出され、変数bには要素数2で各要素にnullが入っている配列がセットされる。この動作はほかの比較演算子「大きいか(-gt)」「小さいか(-lt)」「以上か(-ge)」「以下か(-le)」「異なるか(-ne)」でも同様である。PowerShellでは演算子の左に何が与えられるかで動きを変える、ということを頭の片隅に置いておく必要がある。

比較演算子として、曖昧(あいまい)な比較をしたくなることもある。たとえば文字列があるパターンになっているかどうかをチェックしたいとする。rubyやpythonなら正規表現などを利用するかもしれない。VBAを利用している人であれば、Like演算子があるだろうと頭に浮かぶかもしれない。そう、PowerShellにもLike演算子「-like」が存在する。

"aaanalulabo" -like "*nalulabo"  # => True

ワイルドカードを利用することができるということだ。上記のコードでは先頭からワイルドカードにしているが、後半にも両方にも記述することができる。もしもっと厳密なものにしたい場合は「-clike」を利用することができる。これはケースセンシティブ、つまり大文字小文字を区別するというものだ。

"aaaNalulabo" -clike "*nalulabo"  # => False

もしLike演算を否定したいときは否定演算子である「-not」を別で利用することも可能だが、もっと簡単な組み合わせのLike演算子がある。「-notlike」演算子だ。パターンに合致しないときにTrueを返す。また、この演算子も大文字小文字を区別する「-cnotlike」演算子がある。

Like演算しかできないのか?と疑問に思うかもしれないが、もちろん正規表現を使用した比較も可能だ。「-match」演算子がある。これにも否定形の「-notmatch」、大文字小文字を区別した「-cmatch」がある。これにより、さらに柔軟で複雑なパターンにマッチしているかどうかをチェックすることができる。

さらに、この「-match」演算子では真偽値を返す他に別の作用がある。特殊変数である$Matches変数に正規表現実行の結果が格納されるというおまけがついてくる。否定のものにはこの作用は起こらない。マッチしたものは配列になり、マッチした全体が配列要素の0番目に、部分マッチした箇所は配列の1から順にマッチした値が格納されていく。ただし、この演算子によるマッチ情報は最後にマッチした状態だけを保存している。また次のパターンにマッチしなかった場合にはクリアされることがない。利用は注意が必要だ。

論理演算子

先に否定演算子「-not」を紹介してしまったが、結果を反転させるために利用する。このほかに「-and」や「-or」といったメジャーなものから「-xor」といった論理演算子もある。主には条件分岐のさいに複数の条件がある場合に利用される。

ビット演算子

算術演算に混ぜて左シフト、右シフトを行う演算子を紹介してしまった。シフトのほかにもビットの「b」がつくビット演算子が存在している。バイナリファイルを扱うときなどに利用する可能性があるが、こうした場合は素直にC#などを利用することをお勧めしたい。

ビット演算子には論理演算子の先頭に「b」がつく「-band」「-bor」「-bnot」「-bxor」を利用することができる。

特殊な比較演算子

PowerShellにはほかのプログラミング言語には存在しない不思議な演算子がある。代表的かつ、よく利用されるものをあげていきたい。

まずは文字列操作専用の演算子「-split」だ。左側に与えられた文字列を右側に与えられた区切り文字で分割した配列を返す。よくあるカンマ区切りのデータを配列にするのはこれが最も簡単な方法だ。

"aaa,bbb,ccc" -split ","  # => ["aaa", "bbb", "ccc"]

なお、区切り文字は1文字でなくても構わない。次の例では「@-@」という不思議な区切り文字パターンを利用している。

"abc@-@abc@-@abc" -split "@-@"  # => ["abc", "abc", "abc"]

次によく利用するのが文字列操作専用の演算子「-replace」だ。左側に与えられた文字列を右側に与えられた2要素の配列で更新した文字列を返す。右側に与えた配列の0番目は検知したいパターン文字列、1番目は置き換えたい文字列となる。

"[email protected]" -replace @("gmail", "outlook")

これはもっと簡単に次のように記述することができる。

"[email protected]" -replace "gmail", "outlook"

この演算子の恐ろしいところは右側に与えた配列の0番目要素が正規表現パターンを利用できるというところだ。上記の例では正規表現を使用していない例だが、丸括弧など正規表現で使用される文字が入ってくると途端に正規表現のパターンマッチを行うようになる。このため、意図しない動作をすることがある。たとえば次の例を見て欲しい。

"(1)nalulabo" -replace "(¥d)", ""

気持ちはお分かりではないかと思うが、丸括弧で囲まれた部分ごと空文字で置換して「nalulabo」という文字列を取り出したいのだ。しかし、結果は「()nalulabo」という結果になる。これは丸括弧が正規表現パターンとして認識された結果であり、丸括弧内にある数値部分だけが空文字に置換されてしまったのだ。つまり意図したとおりにしようとすると右側配列の0番目要素は次のように指定するようになる。

"(1)nalulabo" -replace "\(\d\)", ""

これは意図した結果になる。

ほかに比較演算子の仲間である「-in」演算子や「-contains」演算子が利用されることが多いのだが、このあたりは配列についてお話しするときに後述したい。

results matching ""

    No results matching ""