Bash での変数展開・真偽判定のまとめ

Bash における変数展開、および真偽判定の書き方を色々と試した。ただの学習記録。

変数展開

echo 'Bash 変数展開'
# https://qiita.com/t_nakayama0714/items/80b4c94de43643f4be51

echo
echo '${parameter} : 参照'
parameter='hoge-value'  # 変数を宣言する
echo "${parameter}"

echo
echo '${parameter:-word} : デフォルト値 (代入なし)'
echo "${undefined_parameter:-"hoge-default-1"}"  # シングルクォートで囲むとシングルクォートが出力されるのでダブルクォートを使う
echo "${undefined_parameter} (代入されていない)"

echo
echo '${parameter:=word} : デフォルト値 (代入あり)'
echo "${undefined_parameter:="hoge-default-2"}"
echo "${undefined_parameter} (代入されている)"
unset undefined_parameter  # 値のリセット

echo
echo '${parameter-word} : 変数未定義時デフォルト値 (代入なし)'
echo "${undefined_parameter-"hoge-default-3"}"
echo "${undefined_parameter} (代入されていない)"

echo
echo '${parameter=word} : 変数未定義時デフォルト値 (代入あり)'
echo "${undefined_parameter="hoge-default-4"}"
echo "${undefined_parameter} (代入されている)"
unset undefined_parameter

echo
echo '${parameter:?word} : 未定義時のエラー出力'
# echo "${undefined_parameter?'hoge-undefined'}"  # variables.sh: 行 33: undefined_parameter: hoge-undefined
# echo "${undefined_parameter?}"                  # variables.sh: 行 34: undefined_parameter: パラメータが null または設定されていません

echo
echo '${parameter:+word} : 定義時の代用'
echo "${parameter:+'other-hoge-value'} (定義済の場合は値が変わる)"
echo "${undefined_parameter:+'other-hoge-value'} (未定義なので何も出ない)"

echo
echo '${parameter:offset} : 部分展開 (文字数指定なし)'
echo "${parameter:5} (6文字目以降の 'value' が出力される)"

echo
echo '${parameter:offset:length} : 部分展開 (文字数指定あり)'
echo "${parameter:5:3} (6文字目から3文字分 'val')"
echo "${parameter:5:-1} (6文字目以降からの残り5文字から -1 を引いた4文字 'valu')"

echo
echo '${!prefix*} : 変数名一覧'
echo "${!BASH*}"  # 'BASH' で始まる変数名一覧
echo "${!BASH@}"  # 同じ

echo
echo '${!name[*]} : 連想配列キー名一覧'
declare -A hash  # 連想配列を定義する
hash['hoge']='hoge-value'
hash['fuga']='fuga-value'
echo "${!hash[*]}"  # キー名が取れる
echo "${!hash[@]}"  # 同じ
echo "${hash[*]}"  # バリューが取れる
echo "${hash[@]}"  # 同じ

echo
echo '${#parameter} : 文字数カウント'
echo "${#parameter}"  # 空白入りの場合、空白も1文字でカウントされる

echo
echo '${#name[*]} : 配列の要素数カウント'
list=('hoge-value' 'fuga-value')  # 配列に要素を2つ入れる
echo "${list[*]}"     # 配列の中身を全出力する
echo "${#list[*]}"    # 配列の要素数をカウントする
list+=('piyo-value')  # 要素を追加する
echo "${list[@]}"     # 配列の中身を全出力する
echo "${#list[@]}"    # 配列の要素数をカウントする

echo
echo '${parameter#word} : 前方一致除去 (最短一致)'
echo "${parameter#hoge-}"  # パターンに一致する部分が除去される
echo "${parameter#*-}"     # '*' で任意のパターンにマッチする

echo
echo '${parameter##word} : 前方一致除去 (最長一致)'
parameter='hoge-hoge-value'  # 長くしてみる
echo "${parameter#*hoge-}"   # 最短一致
echo "${parameter##*hoge-}"  # 最長一致
parameter='hoge-value'  # 戻す

echo
echo '${parameter%word} : 後方一致除去 (最短一致)'
echo "${parameter%-value}"

echo
echo '${parameter%%word} : 後方一致除去 (最長一致)'
parameter='hoge-value-value'  # 長くしてみる
echo "${parameter%-value*}"   # 最短一致
echo "${parameter%%-value*}"  # 最長一致
parameter='hoge-value'  # 戻す

echo
echo '${parameter/pattern/string} : 文字列置換'
echo "${parameter/value/fuga}"   # 'value' を 'fuga' に置換する
echo "${parameter/value}"        # 空白置換で削除
echo "${parameter/#hoge/fuga}"   # 先頭からのマッチ
echo "${parameter/%value/piyo}"  # 末尾からのマッチ

echo
echo '${parameter//pattern/string} : 文字列置換 (該当箇所全置換)'
parameter='hoge-hoge'  # 値を変えておく
echo "${parameter/hoge/fuga}"   # この場合は最初にヒットしたところだけ置換される
echo "${parameter//hoge/fuga}"  # ヒットする全ての箇所が置換される
parameter='hoge-value'  #戻す

echo
echo '${parameter^} : 大文字化'
echo "${parameter^}"   # 先頭だけ大文字化
echo "${parameter^^}"  # 全部大文字化

echo
echo '${parameter,} : 小文字化'
parameter='HOGE-VALUE'
echo "${parameter,}"   # 先頭だけ小文字化
echo "${parameter,,}"  # 全部小文字化

echo
echo '${parameter~} : 大小文字反転'
parameter='Hoge-Value'
echo "${parameter~}"   # 先頭だけ大文字・小文字を反転
echo "${parameter~~}"  # 全部大文字・小文字を反転

真偽判定

echo 'Bash 条件式の真偽を判定する'
# https://tech.nikkeibp.co.jp/it/article/COLUMN/20060227/230901/

echo '-G ファイル : 指定したファイルが存在し、ファイルのグループが現在実行しているユーザであれば真'
echo '-O ファイル : 指定したファイルが存在し、ファイルの所有者が現在実行しているユーザであれば真'
echo '-S ファイル : 指定したファイルが存在し、ソケットであれば真'
echo '-b ファイル : 指定したファイルが存在し、ブロック・デバイスであれば真'
echo '-c ファイル : 指定したファイルが存在し、キャラクタ・スペシャル・ファイルであれば真'
echo '-d ファイル : 指定したファイルが存在し、ディレクトリであれば真 (Drectory)'
echo '-e ファイル : 指定したファイルが存在すれば真 (Exists)'
echo '-f ファイル : 指定したファイルが存在し、通常のファイルであれば真 (File)'
echo '-g ファイル : 指定したファイルが存在し、パーミッションにセット・グループ ID が付いていれば真'
echo '-h ファイル、-L ファイル : 指定したファイルが存在し、シンボリック・リンクであれば真'
echo '-k ファイル : 指定したファイルが存在し、パーミッションにスティッキ・ビットが付いていれば真'
echo '-p ファイル : 指定したファイルが存在し、名前付きパイプであれば真'
echo '-r ファイル : 指定したファイルが存在し、読み取り可能であれば真 (Readable)'
echo '-s ファイル : 指定したファイルが存在し、ファイル・サイズが 1 以上であれば真'
echo '-t ファイル : 指定したファイルが端末でオープンされていれば真'
echo '-u ファイル : 指定したファイルが存在し、パーミッションにセット・ユーザ ID が付いていれば真'
echo '-w ファイル : 指定したファイルが存在し、書き込み可能であれば真 (Writable)'
echo '-x ファイル : 指定したファイルが存在し、実行可能であれば真 (eXecutable)'

echo
echo 'ファイル1 -nt ファイル2 : 指定したファイル1がファイル2より修正時刻が新しければ真 (Newer Than)'
echo 'ファイル1 -ot ファイル2 : 指定したファイル1がファイル2より修正時刻が古ければ真 (Older Than)'
echo 'ファイル1 -ef ファイル2 : 指定したファイル1とファイル2のデバイス番号と i ノード番号が同じであれば真'

echo
echo '文字列、-n 文字列 : 指定した文字列が 1 文字以上であれば真 (Non Zero)'
echo '-z 文字列 : 指定した文字列が 0 文字 (何もない) 状態であれば真 (Zero)'

echo
echo '文字列1 = 文字列2 : 文字列1と文字列2が同じであれば真'
echo '文字列1 != 文字列2 : 文字列1と文字列2が違ければ真'

echo
echo '数値1 -eq 数値2 : 指定した数値1と数値2が同じであれば真 (=)'
echo '数値1 -ne 数値2 : 指定した数値1と数値2が等しくなければ真 (≠ Not Equal)'
echo '数値1 -lt 数値2 : 指定した数値1が数値2より小さければ真 (<)'
echo '数値1 -le 数値2 : 指定した数値1が数値2より小さいか同じであれば真 (<=)'
echo '数値1 -gt 数値2 : 指定した数値1が数値2より大きければ真 (>)'
echo '数値1 -ge 数値2 : 指定した数値1が数値2より大きいか同じであれば真 (>=)'

echo
echo '! 条件式 : 条件式が偽であれば真'
echo '条件式1 -a 条件式2 : 条件式1と条件式2の結果が共に真であれば真 (AND)'
echo '条件式1 -o 条件式2 : 条件式1または条件式2の結果のいずれかが真であれば真 (OR)'

echo
echo 'test コマンド'
test 'aaa' = 'aaa' && echo "$? : Equal"
test 'aaa' = 'bbb' || echo "$? : Not Equal"
test 'aaa' = 'bbb' ;  echo "$? : Result "

echo
echo '[ コマンド'
[ 'aaa' = 'aaa' ] && echo "$? : Equal"
[ 'aaa' = 'bbb' ] || echo "$? : Not Equal"
[ 'aaa' = 'bbb' ] ;  echo "$? : Result "
# '[[' コマンドは Bash 組み込み・未定義の変数をダブルクォートで囲んでいなくてもエラーにならない

echo
echo 'if test'
if test 'aaa' != 'bbb'; then
  echo 'Not Equal'
fi

echo
echo '-a AND -o OR'
test \( 1 = 1 -o 1 -ne 1 \) -a 2 != 2; echo "$?"
# '()' にはそれぞれ '\(' '\)' のようにエスケープが必要

echo
echo '&& AND || OR'
[ 'a' = 'aaa' ] && [ 'b' = 'bbb' ] || [ 'c' = 'c' ] ; echo "$?"

以上。