Bashのcase文の書き方: パターンで分岐処理
- 作成日: 2020-08-23
- 更新日: 2023-12-24
- カテゴリ: Bash
Bashのcase文の書き方
Bashにはcase
文があります。
これはCやJavaScriptで言うところのswitch
文に近いものです。
これを使うと、if
文を使うより分岐処理が簡単に書ける場合があります。
case 1 in
0 ) echo "match 0" ;;
1 ) echo "match 1" ;;
2 ) echo "match 2" ;;
esac
# match 1
case文の構造
case
文は↓のような構造を持っています。
case 値 in
パターン1 ) 処理 ;;
パターン2 ) 処理 ;;
...
パターンn ) 処理 ;;
esca
case
に値を渡し、その値に応じて処理が分岐します。
値にマッチしたパターンの処理が実行され、他の分岐の処理は実行されません。
整数による分岐
case
に整数を渡し、パターンに整数を列挙すると、パターンにマッチした処理が呼ばれます。
↓の場合、case
で評価している値は1
なので、1 )
のケースにマッチします。
case 1 in
0 ) echo "match 0" ;;
1 ) echo "match 1" ;;
2 ) echo "match 2" ;;
esac
# match 1
case
に渡す値は変数にすることも出来ます。
num=1
case "$num" in
0 ) echo "match 0" ;;
1 ) echo "match 1" ;;
2 ) echo "match 2" ;;
esac
# match 1
defaultパターン
先ほどの整数のcase
文ですが、値が0~2
のいずれかでなければ、どの分岐の処理も実行されません。
いずれの分岐にもマッチしない場合の処理を書きたい場合は、パターンにアスタリスク(*
)を使います。
num=3
case "$num" in # <- numには3が入っている
0 ) echo "match 0" ;;
1 ) echo "match 1" ;;
2 ) echo "match 2" ;;
* ) echo "match *" ;; # <- これが実行される
esac
# match *
文字列による分岐
case
には文字列を指定することも出来ます。
($1
はスクリプトの第1引数です)
case "$1" in
"cat" ) echo "match cat" ;;
"dog" ) echo "match dog" ;;
"bird" ) echo "match bird" ;;
* ) echo "match *" ;;
esac
実行結果。
$ bash sample.sh cat
match cat
$ bash sample.sh dog
match dog
$ bash sample.sh bird
match bird
$ bash sample.sh pig
match *
パターンにORを使う
case
のパターンはOR(|
)で繋ぐことが出来ます。
Aのパターン、またはBのパターンのどちらかにマッチさせたい分岐を書く場合に使います。
case "$1" in
"cat" | "Cat" ) echo "match cat|Cat" ;;
"dog" | "Dog" ) echo "match dog|Dog" ;;
"bird" | "Bird" ) echo "match bird|Bird" ;;
* ) echo "match *" ;;
esac
実行結果。
$ bash sample.sh cat
match cat|Cat
$ bash sample.sh Cat
match cat|Cat
$ bash sample.sh dog
match dog|Dog
$ bash sample.sh Dog
match dog|Dog
$ bash sample.sh bird
match bird|Bird
$ bash sample.sh Bird
match bird|Bird
$ bash sample.sh pig
match *
ワイルドカードによるマッチ
Bashのcase
文のパターンにはワイルドカード(*
)を使うことが出来ます。
*
は任意の文字列(空文字を含む)を意味します。
case "$1" in
# 先頭文字が'c'で始まり、任意の文字が続く文字列にマッチする
c* ) echo "match c*" ;;
# 先頭文字が'd'で始まり、任意の文字が続く文字列にマッチする
d* ) echo "match d*" ;;
# 先頭文字が'b'で始まり、任意の文字が続く文字列にマッチする
b* ) echo "match b*" ;;
# 全てにマッチする
* ) echo "match *" ;;
esac
実行結果。
$ bash sample.sh cat
match c*
$ bash sample.sh dog
match d*
$ bash sample.sh bird
match b*
$ bash sample.sh pig
match *
任意の1文字へのマッチ
パターンに?
を使うと任意の1文字にマッチさせることができます。
case "$1" in
# 先頭文字が任意で、2文字目が'a'の文字列にマッチする
?a* ) echo "match ?a*" ;;
# 先頭文字が任意で、2文字目が'o'の文字列にマッチする
?o* ) echo "match ?o*" ;;
# 先頭文字が任意で、2文字目が'i'の文字列にマッチする
?i* ) echo "match ?i*" ;;
* ) echo "match *" ;;
esac
実行結果。
$ bash sample.sh cat
match ?a*
$ bash sample.sh dog
match ?o*
$ bash sample.sh bird
match ?i*
$ bash sample.sh pig
match ?i*
グループによるマッチ
パターンに[]
を使うと、マッチさせる文字をグループ化することが出来ます。
case "$1" in
# 先頭文字にa, b, cのいずれかの文字を含む文字列にマッチする
[abc]* ) echo "match [abc]*" ;;
# A~Zまたはa~zのいずれかの先頭文字を含む文字列にマッチする
# 正規表現とは違い小文字と大文字を区別しないので注意
[A-Z]* ) echo "match [A-Z]*" ;;
# "!"はカッコの中のいずれでもないという意味
# よってa, b, cのいずれでもない文字にマッチする
[!abc]* ) echo "match [!abc]*" ;;
* ) echo "match *" ;;
esac
実行結果。
$ bash sample.sh cat
match [abc]*
$ bash sample.sh dog
match [A-Z]*
$ bash sample.sh bird
match [abc]*
$ bash sample.sh pig
match [A-Z]*
$ bash sample.sh 123
match [!A-Z]
パターンに変数を使用する
パターンは変数に保存することも出来ます。
name="cat"
pat_1="cat"
pat_2="dog"
pat_3="bird"
case "$name" in # <- nameには"cat"が入っている
"$pat_1" ) echo "match $pat_1" ;; # <- これにマッチする
"$pat_2" ) echo "match $pat_2" ;;
"$pat_3" ) echo "match $pat_3" ;;
* ) echo "match *"
esac
# match cat
ワイルドカードやグループを使う場合
ワイルドカードやグループを変数に書くことも出来ますが、それらを使う場合は変数をダブルクオートで囲まないようにします。
ダブルクオートで囲むと文字列として認識されます。
pat_1="c*"
pat_2="[dD]og"
pat_3="[bB]ird"
case "$1" in
$pat_1 ) echo "match $pat_1" ;;
$pat_2 ) echo "match $pat_2" ;;
$pat_3 ) echo "match $pat_3" ;;
* ) echo "match *"
esac
実行結果。
$ bash sample.sh cat
match c*
$ bash sample.sh Dog
match [dD]og
$ bash sample.sh bird
match [bB]ird
使用例
Bashのcase
文の使用例です。
メールアドレスのドメインごとに分岐する
メールアドレスのドメインごとに処理を分岐します。
case "$1" in
*@gmail.com ) echo "You are gmail user" ;;
*@docomo.co.jp ) echo "You are docomo user" ;;
*@ez.web.jp ) echo "You are AU user" ;;
* ) echo "Unknown" ;;
esac
実行結果。
$ bash a.sh ababa@gmail.com
You are gmail user
$ bash a.sh ababa@docomo.co.jp
You are docomo user
$ bash a.sh ababa@ez.web.jp
You are AU user
$ bash a.sh ababa@infoseek.jp
Unknown
終了確認プロンプト
「本当に終了しますか?」というプロンプトを出して入力に応じて処理を分岐します。
while true; do
echo "本当に終了しますか?(y/n)"
read line
case "$line" in
[yY]es | [yY] ) break ;;
[nN]o | [nN] ) echo "続行します。" ;;
* ) echo "不正な入力です。" ;;
esac
done
実行結果。
$ bash sample.sh
本当に終了しますか?(y/n)
n
続行します。
本当に終了しますか?(y/n)
No
続行します。
本当に終了しますか?(y/n)
ababa
不正な入力です。
本当に終了しますか?(y/n)
Yes
問題
Q1: case
文のパターンに使えるデータを答えよ
- 数値
- 文字列
- パターン
Q2: case
文のパターンで変数を使う場合の注意事項を答えよ
- ワイルドカードやグループを使う場合は変数をバッククオートで囲ってはならない
- ワイルドカードやグループを使う場合は変数をダブルクオートで囲ってはならない
- ワイルドカードやグループを使う場合は変数をダブルクオートで囲む
Q3: case
文のパターンで「先頭にa, b, cのいずれかを含む文字列」として適当なパターンを答えよ
- [!abc]*
- [abc]*
- [0-9]*
正解
Q1: 1, 2, 3
Q2: 2
Q3: 2