本記事ではシェルスクリプトの文字列判定に関する以下の内容をまとめています.
- 「〜で始まる/終わる」文字を判定
- 「〜が含まれる」文字を判定
- 文字列の有無による判定
「〜で始まる/終わる」文字を判定
「〜で始まる/終わる」についてコード例と共に見ていきましょう.
例として「m_
で始まる」 を判定する例は以下です.
#!/bin/zsh
match_check=('ab' 'm_b' 'c' 'm_d')
# 要素を1つずつ取り出す
for i in "${match_check[@]}"; do
# m_で始まるか
if [[ "$i" = "m_"* ]]; then
echo $i
fi
done
m_b m_d
if文の条件式でパターンマッチを使用しており[[ "$i" = "m_"* ]]
の"m_"*
が「m_
で始まる」を指定している部分です.1
次に「b
で終わる」を判定する場合を見てみましょう.
#!/bin/zsh
match_check=('ab' 'm_b' 'c' 'm_d')
# 要素を1つずつ取り出す
for i in "${match_check[@]}"; do
# bで終わるか
if [[ "$i" = *"b" ]]; then
echo $i
fi
done
ab m_b
「〜で始まる」と同じようにif文の条件式でパターンマッチを使用しています.
そのためb
で終わるab
, m_b
が出力されていますね.
「〜が含まれる」文字を判定
「〜が含まれる」のコード例は以下のとおりです.
#!/bin/zsh
match_check2=('abc' 'bbc' 'cnn' 'WBS')
for i in "${match_check2[@]}"; do
# bが含まれるか
if [[ "$i" = *"b"* ]]; then
echo $i
fi
done
abc bbc
if文の条件式でパターンマッチを使用し「b
が含まれる」を表現しています.
そのためb
で終わるab
, m_b
が出力されていますね.
大文字と小文字の区別
パターンマッチを使用して判定する場合,アルファベットの大文字小文字は区別されます.
もし区別せずに判定したい場合は条件式を以下のようにします.
if [[ "$i" = *[bB]* ]]; then
*[bB]*
は「b
もしくはB
が含まれる」を表現しています.
文字列の有無による判定
任意の変数に文字列が存在するか否かを確認するにはtest
コマンドの-z
, -n
オプションを使用します.
文字列ありの場合を判定
-n
オプションをつけると「文字列の長さが0でない」場合に真となります.
すなわち,変数に何らかの文字が存在すれば真です.
#!/bin/zsh
moji='moji'
if [ -n "$moji" ]; then
echo '文字あり'
fi
文字あり
変数moji
には4文字の文字列が代入されているのでif
文内の処理が実行されます.
文字列なしの場合を判定
文字が含まれない場合を判定するには-z
オプションを使用します.
-z
オプションは「文字列の長さが0」の場合に真となります.
#!/bin/zsh
moji='moji'
if [ -z "$moji" ]; then
echo '文字あり'
fi
前項のコードのオプションを変更して実行すると今回は何も表示されません.
(変数moji
には文字列が代入されており「文字列の長さが0」ではないためif
文内の処理が実行されていません)
文字列の長さ判定に関する別記法を確認したい方はこちらをクリック
文字列の長さ判定は以下のように記載することも可能です.
しかし,オプション指定の方がシンプルで速度もやや速いです(後述)
#!/bin/zsh
moji='moji'
# 文字列の長さが0で真
if [ "$moji" = "" ]; then
echo '文字なし'
fi
# 文字列の長さが0でない場合に真
if [ "$moji" != "" ]; then
echo '文字あり'
fi
# 条件式は[ "$moji" != "" ]と同義(書き方が違うだけです)
# わかりづらいので非推奨
if [ ! "$moji" = "" ]; then
echo '文字あり'
fi
<速度>
以下のコード・コマンドで速度を確認2したところ両者に大きな差はありませんでした.
str_time.sh
n=0
nn=1000000
moji=''
# オプション比較
while [ $n -le $nn ]; do
if [ -z "$moji" ]; then
:
fi
n=$((n + 1))
done
# 文字列比較
while [ $n -le $nn ]; do
if [ "$moji" = "" ]; then
:
fi
n=$((n + 1))
done
実行
time ./str_time.sh
結果は以下のとおりで,差は微妙ですがオプションの方が高速です.
7.22s user 0.44s system 99% cpu 7.663 total
(オプション)7.61s user 0.44s system 99% cpu 8.061 total
(文字列比較)
文字列の内容で判定
変数に代入されている特定の文字列を確認して条件分岐させたい場合は以下です.
#!/bin/zsh
moji='任意'
if [ "$moji" = "任意" ]; then
echo '任意です'
fi
任意です
test
コマンドで文字列同士を比較するには=
演算子を使用します.
上記のコードでは変数moji
に「任意」が入っているためif文内の処理が実行されています.
否定の場合は!
を使用して以下のように記載すればOKです.
if [ "$moji" != "任意" ]; then
ひとこと
シェルスクリプトの条件式は色々と書き方があるので,なかなかややこしいですね.
もっとよい書き方をご存知の方がいればぜひお知らせください!