Powershell入門 - 06. 条件ステートメント

条件分岐はどのプログラミング言語にも備わっている、プログラミングの中でも重要な機能です。
他の言語をある程度理解していることを前提に、Powershell特有の書き方をメインで説明します。

# 1. 条件分岐の書き方
まずは条件分岐(if文)の文法についてです。
こちらはC言語やJavaに非常に近い書き方となっています。
ただし、条件式の書き方が一癖あるので、注意が必要です。

## 1.1. if文
まずはif文になります。
```powershell
if (条件式) {
	処理
}
```

条件式に書かれた内容が正しい場合のみ、波括弧{}にかかれた処理を実行します。
では、実際の処理を記述しましょう。
新規でスクリプトを開き、以下の処理を記述しましょう。

```powershell
$x = [int](Read-Host "数値を入力")
if($x -ge 0){
    Write-Host "0以上です。"
}
```
まず、1行目で条件分岐とは別の新しいコマンドレットが登場しているので簡単に紹介します。
`Read-Host`はキーボードから入力を受け取るコマンドレットです。
整数型にするために`[int]`というキーワードがついていますが、細かいことは気にせず1行目の処理で整数を受け取れると思ってください。

上記の処理はxが0以上の場合、"0以上です。"と出力する処理になります。
条件式の部分に見慣れない記号`-ge`が書かれていますね。
この記号がPowershellで使用できる**比較演算子**になります。

### 1.1.1. 比較演算子
比較演算子は値の大小関係や等号関係など、2つの値を比較する場合に使用します。
上の例で書かれた`-ge`は「～以上」という意味で数学など一般的な記号でいう「≧」に該当します。
C言語やJavaなどでは、「>=」を使って表現していました。
他の言語を学んできた人はついつい下記慣れた表現で書こうとしてしまうので注意しましょう。

Powershellで使用可能な比較演算子は次のとおりです。

| Powershell |意味 | 英語 |一般的な記法 | C言語、Javaの記法 |
|:--|:--|:--|:--|:--|
|-eq|等しい|**eq**ual|= |== |
|-ne|等しくない|**n**ot **e**qual|≠|!= |
|-gt|より大きい|**g**reater **t**han| > | > |
|-ge|以上|**g**reater than or **e**qual	| ≧ |>= |
|-lt|より小さい|**l**ess **t**han| < | < |
|-le|以下|**l**ess than or **e**qual | ≦ | <= |

---

### 例題1.
以下の変数xについて、20と等しくなければ"yes"と表示する処理を書きなさい。
```powershell
$x = [int](Read-Host "数値を入力")
```
---

## 1.2. else文
else文はif文とともに使われ、if文の条件が成り立たなかったときの処理を記述します。
```powershell
if (条件式) {
	処理A
} else {
	処理B
}
```

以下の例の場合、xが0以上ならば"A"、そうでなければ"B"と表示されます。
```powershell
$x = [int](Read-Host "数値を入力")
if($x -ge 0){
    Write-Host "A"
}else{
    Write-Host "B"
}
```

---
#### 例題2.
以下の文字列変数sについて、"abc"と等しければ"OK"、そうでなければ"NG"と表示しなさい。

```
$s = Read-Host "文字列を入力"
```
---

## 1.3. elseif文
elseif文もif文と一緒に使われます。
```powershell
if (条件式A) {
	処理A
} elseif (条件式B){
	処理B
} 
```
else文との違いですが、else文はif文の条件が成り立たなければ必ず実行されますが、
elseif文は「if文の条件が成り立たず、かつelseif文の条件が成り立つとき」に実行されます。

また、if文、elseif文、else文をすべて使った条件分岐も書くことができます。

```powershell
if (条件式A) {
	処理A
} elseif (条件式B){
	処理B
} else {
	処理C
} 
```
この場合、elseが実行されるのは、「条件式Aも条件式Bも成り立たなかったとき」になります。

以下の例は変数xが①0より大きい、②0より小さい、③それ以外で条件分岐する例です。
```powershell
$x = [int](Read-Host "数値を入力")
if($x -gt 0){
    Write-Host "正"
}elseif($x -lt 0){
    Write-Host "負"
}else{
    Write-Host "ゼロ"
}
```

---
#### 例題3.
以下の文字列変数sについて、
- "春"と等しければ"Spring"
- "夏"と等しければ"Summer"
- "秋"と等しければ"Autumn"
- そうでなければ"Winter"

と表示しなさい。

```
$s = Read-Host "文字列を入力"
```
---

## 1.4. Nullの判定方法
例えば、配列の添字を超えてアクセスした場合や、存在しない属性にアクセスした場合、結果には空のオブジェクトを表す**Null**が入ります。
```powershell
$a = 1..10
Write-Host $a[100]                            # 何も表示されない
$b = Get-ChildItem -Path D:\powershell\data
Write-Host $b.Huga                            # 何も表示されない
```

Nullは思いもよらない動作を引き起こす可能性があるため、Nullのチェックは重要です。
Nullかどうかの判定は以下のように記述します。

```powershell
$a = 1..10
if($null -ne $a[100]){
    Write-Host $a[100]
}else{
    Write-Host "a[100]はNullです"
} 
```

---

#### 例題5.
以下の変数bについて、1～3の属性があるかどうか判定し、ある場合だけその属性の値を表示しなさい。
ない場合、この属性は存在しませんと表示すること

```powershell
$b = Get-ChildItem -Path D:\powershell\data
```
確認する項目
1. $b.BaseName
2. $b.Exists
3. $b.Date
---

## 1.5. 特定の値が配列や文字列に含まれるか判定する
配列に特定の値が含まれているかどうかを判定する場合、`$配列名.Contains()`メソッドが使えます。
使い方は以下の通りです。
```powershell
$a = 1..10
$x = [int](Read-Host "数値を入力")
if($a.Contains($x)){
    # なにもしない
}else{
    $a += $x
}
Write-Host $a
```

`$配列名.Contains()`は配列内にその値が含まれていれば真、そうでなければ偽となります。
この例では、含まれていなければその値を配列の末尾に追加しています。

ちなみに何もしない場合は、処理の中身を空にしておけばOKです。

また、文字列についても同じことができます。
```powershell
if($文字列.Contains(検索対象){
   ・・・
}
```

---
#### 例題6.
変数xに格納された文字列が変数sに含まれていれば"Contains!!"、そうでなければ変数sの末尾に変数xを結合しなさい。
```powershell
$s = "abcdefghijklmnopqrstuvwxyz"
$x = Read-Host "文字列を入力"
```
---

# 2. 論理演算子
条件分岐の条件式に書ける項目は、真か偽か(正しいか間違っているか)の2択になるものに限ります。
真か偽かに分かれるような値を**論理値**と言います。
また、論理値は**論理演算子**を使って、新しい条件を作ることが可能です。

| Powershell |意味 | 英語 |C言語、Javaの記法 |
|:--|:--|:--|:--|
|A -and B| A かつ B| A and B| A && B |
|A -or B| A または B| A or B | A \|\| B |
|-not A| A でない | not A| ~A |

まずは、上の2つを見ていきましょう。

## 2.1. 複数の条件を結合する
`-and`や`-or`を使うことで、２つの条件をつなげることができます。

`-and`の場合、「2つの条件の両方とも正のときのみ正」となります。
一方で`-or`は、「2つの条件のいずれか一方でも正のときは正」となります。
意味が異なるので、自分が書きたい条件がどちらかによって上手に使い分けましょう。

以下は変数xの値が10以上20以下の場合に”Yes"、そうでなければ"No"と表示する処理です。
```powershell
$x = [int](Read-Host "数値を入力")
if($x -ge 10 -and $x -le 20 ){
    Write-Host "Yes"
}else{
    Write-Host "No"
}
```

---
#### 例題7.
以下の変数monthの値が6,7,8のいずれかの場合、”Summer"と表示する処理を書きなさい。

```powershell
$month = [int](Read-Host "数値を入力")
```
---

## 2.2. 条件を否定する
`-not`は条件式の真と偽を逆転させる作用があります。
例えば、`$x -eq 10`という条件があった場合、xが10ならば真、それ以外ならば偽です。
ですが、`-not ($x -eq 10)`という条件の場合、xが10ならば偽、それ以外は真となります。

条件を否定するケースが浮かばないという人もいると思います。
1.5で紹介したケースを思い出しましょう。

```powershell
$a = 1..10
$x = [int](Read-Host "数値を入力")
if($a.Contains($x)){
    # なにもしない
}else{
    $a += $x
}
Write-Host $a
```

このケースでは、配列aがxを含むときを真としているため、何もしないからのif文が存在してしまいます。
このような場合は、条件を否定したほうがスクリプトがスッキリします。

```powershell
$a = 1..10
$x = [int](Read-Host "数値を入力")
if(-not $a.Contains($x)){
    $a += $x
}
Write-Host $a
```

---
#### 例題8.
例題6の条件文を否定した形で書き換えなさい。

---

Prev : [05.スクリプト化](./436047504e2365c5bd03)
Next : [07. ループステートメント](./fcb962e20acffac54951)

[目次へ戻る](./926b8053a031539437a3)