bashで正規表現を使う方法

bashシェルスクリプト正規表現を使う方法をまとめます

正規表現でパターンマッチ

bash演算子 "=~" を使います

x=1234
if [[  $x =~ ^[0-9]+$ ]]; then
   echo "x is number"
else
   echo "x is not number"
fi

正規表現で部分文字列を取り出す

マッチした部分文字列が必要な場合は,bashの組み込み変数 BASH_REMATCH を使います

x=1234-ABC
if [[  $x =~ ^(.*)-(.*)$ ]]; then
   echo ${BASH_REMATCH[1]}
   echo ${BASH_REMATCH[2]}
else
   echo "not matched"
fi

正規表現でパターンマッチするときの注意事項

正規表現を”(クオート)で括ると動きません

以下のコードは期待通りに動作しません.

x=1234
if [[  $x =~ "^[0-9]+$" ]]; then
   echo "x is number"
else
   echo "x is not number"
fi

bashは^[0-9]+$ を正規表現と解釈しますが,「”」で括った "^[0-9]+$"は文字列として解釈するためです

よくハマる罠になるので,慣れないうちは正規表現は変数に入れてから使用するクセをつけたほうが安全かもしれません

x=1234
pattern="^[0-9]+$"
if [[  $x =~ $pattern ]]; then
   echo "x is number"
else
   echo "x is not number"
fi

2行目で変数patternに正規表現を入れていますが,この場合は「”」の有無に関わらず期待通りに動作します

別解: 外部コマンドgrepを使って 正規表現でパターンマッチする

grepを使う方法もあります

x=1234
echo $x | grep -E "^[0-9][0-9]*$" > /dev/null 2>&1
if [ $? -eq 0 ]; then
   echo "x is number"
else
   echo "x is not number"
fi

正規表現で文字列を置換する

bashの置換機能を使います.bash

  • ${変数名/置換文字列/置換後の文字列}
  • ${変数名//正規表現/置換後の文字列}

という書き方ができます

x=abc123
echo ${x//[0-9]/X}

別解: 外部コマンドsed を使って 正規表現で置換する

x="abc123"
y=`echo $x | sed -e 's,[0-9],X,g'`
echo $y

別解: bashの組み込み変数 BASH_REMATCH を使う方法

実用性は皆無ですが,BASH_REMATCHを使うと正規表現で文字列の置換が実装できます

y=abc123
pattern='(.+)[0-9](.*)'
while [[ $y =~ $pattern ]]; do
    y=${BASH_REMATCH[1]}X${BASH_REMATCH[2]}
done
echo  $y