| パターン | 動作 | 典型的な使用例 |
|---|---|---|
| ${変数#パターン} | 文字列先頭の最短マッチ部分を削除 | 単に先頭の固定文字列を削除するとき使う |
| ${変数##パターン} | 文字列先頭の最長マッチ部分を削除 |
${HOGE##*/}でbasename |
| ${変数%パターン} | 文字列末尾の最短マッチ部分を削除 |
${HOGE%/*}でdirname。単に末尾の固定文字列を削除するときにも使う |
| ${変数%%パターン} | 文字列末尾の最長マッチ部分を削除 | あまり使わない |
| ${変数/検索文字列/置換文字列} | 最初にマッチしたもののみ文字列を置換 | |
| ${変数//検索文字列/置換文字列} | 全ての文字列を置換 | ${HOGE//foo/bar} |
これらの置換機能はParameter Expansion(変数展開)という機能の一部である。公式ドキュメント
#と%が覚えづらい。
#はmarkdownで行頭に書くと見出しになるから「先頭の」
%は100%のように末尾に書くから「末尾の」
と覚えるといいかも。
キーボードで#は%より左にあるから#が先頭と覚えてもいいかも。
% %% # ## はPOSIXで規定されている機能であり、bash以外のshでも使えるらしい。2.6.2 Parameter Expansionに書いてある。
具体例
dirname
HOGE="/var/log/httpd/access.log"
echo ${HOGE%/*} #=> /var/log/httpd
ただし$HOGEが1個も/を含まない場合はうまくいかないので注意:
HOGE="moge.txt"
echo ${HOGE%/*} #=> moge.txt(本来は「.」になってほしい)
/を含むかどうか判定するにはこのようにすればよい:
mydirname() {
if [[ $1 == */* ]]; then
echo ${1##*/}
else
echo "."
fi
}
basename
HOGE="/var/log/httpd/access.log"
echo ${HOGE##*/} #=> access.log
HOGE="moge.txt"
echo ${HOGE##*/} #=> moge.txt
拡張子を取得
HOGE="/var/log/httpd/access.log"
echo ${HOGE##*.} #=> log
HOGE="moge.txt"
echo ${HOGE##*.} #=> txt
ただしHOGEがピリオドを1個も含まない場合は元の文字列全体になってしまうので注意:
HOGE="/var/log/httpd/access"
echo ${HOGE##*.} #=> /var/log/httpd/access
拡張子を削除
HOGE="/var/log/httpd/access.log"
echo ${HOGE%.*} #=> /var/log/httpd/access
HOGE="moge.txt"
echo ${HOGE%.*} #=> moge