LoginSignup
196
185

More than 5 years have passed since last update.

bash Tips - コマンド置換と算術式展開、パラメータ展開

Last updated at Posted at 2014-08-17

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組み込みであり、インクリメントできるから
exprはインクリメントできない
# i=1; i=$( expr ++$i ); echo "$i"
++1
ダラーと丸括弧2重ならインクリメントできる
# i=1; i=$((++i)); echo "$i"
2

算術式展開
  算術式展開を使うと、算術式を評価して、その結果に置換できます。
  算術式展開のフォーマットを次に示します:
    \$((expression))

  expression はダブルクォート内部にある場合と同様に扱われますが、
  括弧の内側のダブルクォートが特別扱いされることはありません。
  式に含まれる全てのトークンに対して、
  パラメータ展開・文字列展開・コマンド置換・クォートの削除が行われます。
  算術式置換は入れ子にできます。

  評価は後述の 算術式評価で示す規則に基づいて行われます。
  expression が不正であれば、 bash は評価の失敗を示すメッセージを出力し、置換を全く行いません。
                                       man bash より引用

パラメータ展開

${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 より引用

196
185
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
196
185