Help us understand the problem. What is going on with this article?

bashの変数内文字列置換まとめ

More than 1 year has passed since last update.
パターン 動作 典型的な使用例
${変数#パターン} 文字列先頭最短マッチ部分を削除 単に先頭の固定文字列を削除するとき使う
${変数##パターン} 文字列先頭最長マッチ部分を削除 ${HOGE##*/}でbasename
${変数%パターン} 文字列末尾最短マッチ部分を削除 ${HOGE%/*}でdirname。単に末尾の固定文字列を削除するときにも使う
${変数%%パターン} 文字列末尾最長マッチ部分を削除 あまり使わない
${変数/検索文字列/置換文字列} 最初にマッチしたもののみ文字列を置換
${変数//検索文字列/置換文字列} 全ての文字列を置換 ${HOGE//foo/bar}

#%が覚えづらい。
#はmarkdownで行頭に書くと見出しになるから「先頭の」
%100%のように末尾に書くから「末尾の」
と覚えるといいかも。

% %% # ## はPOSIXで決まっているのでbash以外でも使えるらしい。2.6.2 Parameter Expansionに書いてある。
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html

具体例

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
aosho235
1981年生まれ。駅すぱあとの会社で新規サービスを開発しています。好きなものはOS~ミドルウェアのレイヤー、開発を楽にするためのツールやフレームワークの整備、自分自身が便利だと思うものを作ること。最新技術を追うことより、自分が自信を持って使える技術で効率的に開発することを好みます。
https://aosho235.com/
val
経路検索システム「駅すぱあと」をはじめ、全国のデータと高い信頼性をベースにさまざまなサービスを展開。
https://www.val.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away