第19回 case文で分岐を整理しよう:パターンマッチと;;の基本 | はじめてのシェルスクリプト

* 当サイトでは、コンテンツの一部に広告を掲載しています。

System Note $ cat /proc/ai-disclosure

本記事の構成および論理分析にはAI(人工知能)を使用しています。情報の正確性は、システム管理者(UNIXユーザー)による手動検証済みです。

第19回 case文で分岐を整理しよう:パターンマッチと;;の基本 | はじめてのシェルスクリプト

はじめてのシェルスクリプト | 第19回

目次

はじめに

この連載では、macOS のターミナルで sh を使いながら、シェルスクリプトの基本を順番に学んでいきます。

第8回・第9回では、if 文と条件式を使って処理を分岐させる方法を学びました。「条件が成り立つかどうか」を判定して処理を切り替えるのが if 文の強みです。

一方で、「入力された値が A なら〇〇、B なら△△、C なら□□」といった、複数の候補から選ぶような分岐を if 文で書くと、コードが縦に長くなりがちです。こういったパターンに適した構文が、シェルスクリプトの case 文です。

第19回では、case 文の基本的な書き方と、パターンマッチを使った分岐の整理の仕方を学びます。if 文との使い分けを理解しておくと、読みやすいスクリプトが書けるようになりますよ。

この回で学ぶこと

  • case 文とは何か
  • パターンごとに処理を書く形
  • ;; の役割
  • 複数候補をまとめる書き方
  • 入力値に応じて処理を分ける方法
  • if との使い分け
  • 初学者がつまずきやすい書き方

case文とは何か

値に応じて処理を分ける

case 文は、ひとつの値に対して複数の候補を順番に確認し、合った処理を実行する書き方です。

if 文でも分岐はできますが、候補が増えてくると case 文の方が整理しやすくなります。

基本の形

基本の形は次のとおりです。

case "$value" in
  pattern1)
    処理
    ;;
  pattern2)
    処理
    ;;
esac

case で始まり、最後は esac で閉じます。

;; の役割

;; は、そのパターンの処理が終わったことを示します。

これを書かないと、case 文として正しく解釈されません。

サンプルコード

case_sample.sh に次の内容を保存します。

#!/bin/sh

echo "好きな文字を入力してください: a / b / c"
read answer

case "$answer" in
  a)
    echo "a が入力されました"
    ;;
  b)
    echo "b が入力されました"
    ;;
  c)
    echo "c が入力されました"
    ;;
  *)
    echo "a / b / c 以外が入力されました"
    ;;
esac

実行手順

1. ファイルを作成して保存する

エディタで case_sample.sh という名前のファイルを作成し、次の内容を保存します。

#!/bin/sh

echo "好きな文字を入力してください: a / b / c"
read answer

case "$answer" in
  a)
    echo "a が入力されました"
    ;;
  b)
    echo "b が入力されました"
    ;;
  c)
    echo "c が入力されました"
    ;;
  *)
    echo "a / b / c 以外が入力されました"
    ;;
esac

2. スクリプトを実行する

次のコマンドを実行します。

sh case_sample.sh

a を入力した場合の実行結果の例です。

好きな文字を入力してください: a / b / c
a
a が入力されました

x を入力した場合の実行結果の例です。

好きな文字を入力してください: a / b / c
x
a / b / c 以外が入力されました

コードの読み方

case “$answer” in

変数 answer の値を確認し、その値に合うパターンを探します。

変数は "..." で囲んでおくと、空白を含む場合でも安全に扱いやすくなります。

a)b)

a) は、値が a だった場合の処理を表します。

b)c) も同じ考え方です。

*)

* は、どの候補にも一致しなかった場合を表します。

case 文では、最後に *) を書いておくと、想定外の入力にも対応しやすくなります。

複数候補をまとめる

case 文では、複数の候補を | で並べてまとめることができます。

case "$answer" in
  y|Y)
    echo "yes が選ばれました"
    ;;
  n|N)
    echo "no が選ばれました"
    ;;
  *)
    echo "y か n を入力してください"
    ;;
esac

このように書くと、似た意味の入力をひとつの処理にまとめられます。

if文との使い分け

値がひとつの候補に当てはまるかどうかを細かく判定したい場合は、if 文が向いています。

一方で、ひとつの値を複数の候補に分けて整理したい場合は、case 文が向いています。

特に、「入力が startstoprestart か」のように候補が並ぶ場合は、case 文の方が読みやすくなります。

初学者がつまずきやすい点

esac を書き忘れる

case 文は fi ではなく esac で終わります。

ここを間違えると構文エラーになります。

;; を書き忘れる

各パターンの最後には ;; が必要です。

これがないと、どこで処理が終わるかを正しく区切れません。

* を最後に書く

* はどの値にも一致しやすいため、通常は最後に書きます。

先に書いてしまうと、後ろの候補が使われなくなることがあります。

よくあるエラー

parse error near

;;esac の書き忘れがないか確認してください。

case 文は記号の数が増えるため、区切りの抜けが起きやすいです。

想定した分岐に入らない

入力された値が本当にその候補と一致しているか確認してください。

大文字と小文字が違うだけでも別の値として扱われます。

どの入力でも最後の処理になる

*) を先に書いていないか確認してください。

* は広い範囲に一致するため、位置が重要です。

練習用コード

次の内容で menu_sample.sh を作成して実行してみてください。

#!/bin/sh

echo "数字を入力してください: 1 / 2 / 3"
read menu

case "$menu" in
  1)
    echo "設定を表示します"
    ;;
  2)
    echo "一覧を表示します"
    ;;
  3)
    echo "終了します"
    ;;
  *)
    echo "1 から 3 の数字を入力してください"
    ;;
esac

入力する数字を変えて、実行結果がどう変わるか確認してください。

この回で理解しておくこと

  • case 文は、ひとつの値を複数の候補に分けて処理できる
  • 各パターンは 候補) の形で書く
  • 各処理の最後には ;; が必要である
  • 一致しなかった場合は *) で処理できる
  • 複数候補は | でまとめられる
  • 候補が多い分岐では if 文より整理しやすい

まとめ

今回は、case 文を使って複数の候補ごとに処理を分ける方法を確認しました。

候補が増える分岐では、if 文を並べるよりも case 文の方が見通しよく書ける場面があります。

次回は、sh の位置パラメータをまとめて扱う基本を学びます。

次回予告

次回は「位置パラメータをまとめて扱おう」です。

複数の値をまとめて扱うための基本を確認します。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

のいのアバター のい UNIX Cafe マスター

Macintosh Color Classicから始まった旅は、長いWindows時代を経て、Windows10のサポート終了をきっかけにUNIXの世界へ戻ってきました。UNIX Cafeでは、UNIX・Linux・そしてMacな世界を、むずかしい言葉を使わず、物語のように書いています。プログラミングは、アイデアをコンピューターに伝えるための言葉です。簡単な単語と文法を覚えれば、誰でもコマンドを使えます。ぜひ一度、やさしいプログラミングの世界をのぞいてみてください。

Created by UNIX Cafe

目次