bash Tips - コマンド置換と算術式展開、パラメータ展開
コマンド置換 - `command`
ではなく$(command)
を使う
- なぜか?ネストできるから
# echo `echo "0123456789abcdefg" | cut -b `echo "11"``
cut: option requires an argument -- 'b'
詳しくは `cut --help' を実行して下さい.
echo 11
# echo $(echo "0123456789abcdefg" | cut -b $(echo "11"))
a
コマンド置換
コマンド置換 (command substitution) を用いると、コマンド名をコマンドの出力で置き換えできます。
コマンド置換には以下の 2 つの形式があります:
$(command)
または
`command`bash による展開は、command の実行およびコマンド置換の部分をコマンドの標準出力と
置換することにより実行されます。
この際、末尾の改行文字は削除されます。
文字列の途中にある改行文字は削除されませんが、単語分割の際に削除されることがあります。
コマンド置換 $(cat file) は、同じ意味を持ち、しかも高速な $(< file) に置き換え可能です。バッククォートを使う古い形式の置換を用いたとき、
バックスラッシュは文字通りの意味を保ちますが、$、 '、 \、の前にある場合は例外となります。
バックスラッシュが前置されていないバッククォートがあると、そこでコマンド置換は閉じられます。
$(command) という形式を用いたときは、括弧の間にある全ての文字がコマンドとなります。
特別扱いされる文字はありません。コマンド置換は入れ子にできます。
バッククォート形式の時に入れ子を行うには、
内側のバッククォートをバックスラッシュでエスケープします。置換がダブルクォート内部にある場合には、
置換の結果に対する単語分割とパス名展開は行われません。
man bash より引用
算術式展開 - expr $m + $n
ではなく$((m+n))
を使う
- なぜか?bash組み込みであり、インクリメントできるから
# i=1; i=$( expr ++$i ); echo "$i"
++1
# i=1; i=$((++i)); echo "$i"
2
算術式展開
算術式展開を使うと、算術式を評価して、その結果に置換できます。
算術式展開のフォーマットを次に示します:
$((expression))expression はダブルクォート内部にある場合と同様に扱われますが、
括弧の内側のダブルクォートが特別扱いされることはありません。
式に含まれる全てのトークンに対して、
パラメータ展開・文字列展開・コマンド置換・クォートの削除が行われます。
算術式置換は入れ子にできます。評価は後述の 算術式評価で示す規則に基づいて行われます。
expression が不正であれば、 bash は評価の失敗を示すメッセージを出力し、置換を全く行いません。
man bash より引用
パラメータ展開
- matsuiによるページを参照
${parameter:-word}
デフォルトの値を使います。 parameter が設定されていないか空文字列であれば、 word を展開したものに置換されます。そうでなければ、 parameter の値に置換されます。${parameter:=word}
デフォルトの値を代入します。 parameter が設定されていないか空文字列であれば、 word を展開したものが parameter に代入されます。それから parameter の値への置換が行われます。 位置パラメータや特殊パラメータへの代入をこのように行うことはできません。${parameter:?word}
空文字列または設定されていない場合にエラーを表示します。 parameter が空文字列または設定されていない場合、word を展開したもの (word がなければ パラメータが空文字列または設定されていないことを示すメッセージ) が標準エラー出力に出力されます。シェルが対話的でなければ、 シェルは終了します。パラメータに空文字列以外が設定されていれば、 parameter の値への置換が行われます。${parameter:+word}
別の値を使用します。 parameter が空文字列または設定されていなければ、空文字列に置換されます。 そうでなければ word を展開したものに置換されます。${parameter:offset:length}
部分文字列展開。 parameter を展開したものから最大 length 文字を取り出します。 先頭の文字は offset で指定します。length を省略すると、 offset で指定した文字を先頭にして、 parameter の残り全部が含まれる部分文字列に展開します。 length と offset は算術式です (後述の 算術式評価 を参照)。 offset を評価すると 0 未満の数になる場合、この値は parameter の値の末尾からのオフセットとして使われます。 length を評価すると 0 未満の数になる場合、 parameter が @ ではなく、配列でも連想配列でもなければ、 この値は文字数ではなく parameter の値の末尾からのオフセットとして使われ、 展開結果は 2 つのオフセットの間の部分文字列となります。 parameter が @ ならば、結果は offset から始まる length 個の位置パラメータになります。 parameter が @ または * のインデックスが付いている配列名ならば、 結果は配列の ${parameter[offset]} を先頭とする要素 length 個となります。 負の offset は、指定された配列の最大のインデックス + 1 からの相対値と解釈されます。 連想配列に部分文字列展開した場合の結果は決められていません。 負のオフセットを指定するときには、:- 式と混同されないよう、 1 つ以上の空白でコロンと離す必要があることに注意してください。 位置パラメータを使う場合以外は、 部分文字列のインデックスは 0 から始まります。位置パラメータの場合には、 インデックスは 1 から始まります。 位置パラメータが使われて offset が 0 の場合、 $0 の値が先頭に置かれます。${!prefix*}
${!prefix@}
前方一致する変数名。 prefix で始まる全ての変数の名前に展開して、 IFS 特殊変数の最初の文字によって区切ります。 ダブルクォートの中で @ が使われた場合、それぞれの変数の名前は 別々の単語に展開されます。${!name[@]}
${!name[*]}
配列のキーのリスト。 name が配列変数であれば、配列 name の インデックス (キー) のリストに展開されます。 name が配列でない場合は、name が設定されていれば 0 に、 そうでなければ空に展開されます。 ダブルクォートの中で @ が使われた場合、それぞれのキーは 別々の単語に展開されます。${#parameter}
パラメータの長さ。 parameter の値に含まれる文字数に置換されます。 parameter が * または @ ならば、位置パラメータの数に置換されます。 parameter が * または @ が添字になっている配列名ならば、配列中の要素数に置換されます。${parameter#word}
${parameter##word}
パターンに前方一致した部分を取り除く。 word が展開され、パス名展開の場合と同じようなパターンを作ります。 このパターンが parameter の値の先頭部分とマッチする場合、展開して得られる値は parameter を展開した値から最短一致パターン (#''の場合) または最長一致パターン (
##'' の場合) を取り除いたものになります。 parameter が @ または * である場合、 パターンを削除する操作は全ての位置パラメータに順番に適用され、 展開結果はリストとして得られます。 parameter が @ または * が添字になっている配列変数である場合、 パターンを削除する操作は配列の全ての要素に順番に適用され、 展開結果はリストとして得られます。${parameter%word}
${parameter%%word}
パターンに後方一致した部分を取り除く。 word が展開され、パス名展開の場合と同じようなパターンを作ります。 このパターンが parameter を展開した値の末尾の部分とマッチする場合、展開結果は parameter を展開した値から最短一致パターン (%'' の場合) または最長一致パターン (
%%'' の場合) を取り除いたものになります。 parameter が @ または * である場合、 パターンを削除する操作は全ての位置パラメータに順番に適用され、 展開結果はリストとして得られます。 parameter が @ または * が添字になっている配列変数である場合、 パターンを削除する操作は配列の全ての要素に順番に適用され、 展開結果はリストとして得られます。${parameter/pattern/string}
パターンの置換。 pattern が展開され、 パス名展開の場合と同じようなパターンを作ります。 parameter の展開が行われ、 その値のうち pattern に最長一致する部分が string に置換されます。 pattern が / で始まる場合には、pattern に マッチした部分は全て string に置換されます。 そうでない場合には、最初にマッチした部分だけが置換されます。 pattern が # で始まる場合には、パターンは parameter を展開した値の先頭にマッチしなければなりません。 pattern が % で始まる場合には、パターンは parameter を展開した値の末尾にマッチしなければなりません。 string が空の場合には pattern にマッチした部分は削除されます。 またこの場合には、pattern の後に続く / は省略可能です。 parameter が @ または * である場合、置換操作は全ての位置パラメータに順番に適用され、 展開結果はリストとして得られます。 parameter が @ または * が添字になっている配列変数である場合、 置換操作は配列の全ての要素に順番に適用され、 展開結果はリストとして得られます。${parameter^pattern}
${parameter^^pattern}
${parameter,pattern}
${parameter,,pattern}
大文字小文字の変換。 parameter に含まれるアルファベットの大文字小文字を変換します。 pattern が展開され、 パス名展開の場合と同じようなパターンを作ります。 ^ 演算子は pattern にマッチした小文字を大文字に変換します。 , 演算子は pattern にマッチした大文字を小文字に変換します。 ^^ 演算子と ,, 演算子は、マッチした全ての文字を変換します。 ^ 演算子と , 演算子の場合は、マッチした最初の文字だけ変換します。 pattern を省略した場合、? を指定したものとして扱われ、 全ての文字にマッチします。 parameter が @ または * である場合、大文字小文字の変換は全ての位置パラメータに順番に適用され、 展開結果はリストとして得られます。 parameter が添字に @ または * の付いた配列変数の場合は、配列の要素のそれぞれに大文字小文字の変換が適用され、 結果はリストに展開されます。man bash より引用