Bash使いなら覚えておきたい!変数値を置換する方法まとめ! | Linux Fan

Bash使いなら覚えておきたい!変数値を置換する方法まとめ!

2018年7月20日

シェル(Bash)で作業している時や、シェルスクリプトを書いている時、変数などに設定された値(文字列)を置換して使いたいことがあります。

そんな時に使えるのが、パラメーター展開時のパターンマッチによる置換機能です。

変数値の置換書式

変数値(変数に設定された文字列)の置換は次の書式で行います。

${変数名#パターン}
変数に設定された文字列から、「パターン」に前方一致した部分を取り除いたものに展開される。取り除かれるのは「最短一致」した部分。
${変数名##パターン}
変数に設定された文字列から、「パターン」に前方一致した部分を取り除いたものに展開される。取り除かれるのは「最長一致」した部分。
${変数名%パターン}
変数に設定された文字列から、「パターン」に後方一致した部分を取り除いたものに展開される。取り除かれるのは「最短一致」した部分。
${変数名%%パターン}
変数に設定された文字列から、「パターン」に後方一致した部分を取り除いたものに展開される。取り除かれるのは「最長一致」した部分。
${変数名/パターン/文字列}
変数に設定された文字列から、「パターン」に一致した部分を指定文字列に置換して展開される。置換されるのは最初に一致したもののみ
${変数名//パターン/文字列}
変数に設定された文字列から、「パターン」に一致した部分を指定文字列に置換して展開される。一致したものすべてが置換される。

なお、各「パターン」にはパス展開で使われる以下の表現を用いることができます。

*(アスタリスク)
長さ0以上の文字列にマッチします。
?(疑問符)
任意の一文字にマッチします。
[文字](角括弧で括られた文字)
括られた文字のうちいずれかにマッチします。[a-z](アルファベットの小文字aからzまでの文字)のように範囲で指定することもできます。
[^文字] もしくは [!文字]
括られた文字以外の文字のいずれかにマッチします。[^0-9](数字以外の文字)のように範囲で指定することもできます。

変数値の置換例

$ f=/etc/systemd/system
$ echo $f
/etc/systemd/system

# 先頭の「/etc」を削除して出力
$ echo ${f#/etc}
/systemd/system

# 先頭から「/*/」に最短一致する部分を削除して出力
$ echo ${f#/*/}
systemd/system

# 先頭から「/*/」に最長一致する部分を削除して出力
$ echo ${f##/*/}
system

# 末尾の「system」を削除して出力
$ echo ${f%system}
/etc/systemd/

# 末尾から「/system*」に最短一致する部分を削除して出力
$ echo ${f%/system*}
/etc/systemd

# 末尾から「/system*」に最長一致する部分を削除して出力
$ echo ${f%%/system*}
/etc

# 「system」を「init」に1回だけ置換して出力
$ echo ${f/system/init}
/etc/initd/system

# 「system」をすべて「init」に置換して出力
$ echo ${f//system/init}
/etc/initd/init