Qbilinux 日記

Linux に関係することだけではなく,最近は一般的なコンピュータやガジェット関係についても記載してます.

bash での変数を加工する方法のメモ

自分用のメモで,単なるマニュアルからの転載です.

bash script 中で変数の一部を削除とか置換するときに毎回なんだったっけ?って探すのでメモ代わりに,有益&なんだったっけ?ってなりやすいものを bash マニュアルから転載してみる.気になるところはちょこっと色をつけておく.

パラメータの展開

`$' 文字があると、パラメータ展開、コマンド置換、 算術式展開が行われます。展開されるパラメータ名やシンボルは、 ブレースで括ることもできます。 ブレースは省略可能ですが、 変数の直後に変数名の一部と解釈できる文字が置かれた場合に、 その文字と共に変数が展開されてしまうのを防ぐために用意されています。

ブレースを使った場合、対になるのは最初に表れる `}' です。 ただしバックスラッシュでエスケープされているものや クォートされている文字列中のものは含まれませんし、ブレースの内側にある 算術式展開やコマンド置換、パラメータ展開に入っているものも含まれません。

${parameter}

parameter の値に置換されます。ブレースが必要になるのは、 parameter が 2 桁以上の数字を持つ位置パラメータの場合や、 parameter の直後の文字を名前の一部として解釈させたくない場合です。

parameter の最初の文字が感嘆符ならば、変数間接展開が行われます。 bash は残りの parameter からなる変数の値を変数の名前と見なします。 そしてそこで得られた名前の変数を展開した値を、置換処理の続きで使います。 これが 間接展開 です。 ただし ${!prefix*} や ${!name[@]} の展開は例外です。 これは以下で説明します。 間接展開を表すには、感嘆符は左ブレースの直後に続ける必要があります。

以下に示すそれぞれの場合、word に対してチルダ展開、 パラメータ展開、コマンド置換、算術式展開が行われます。
部分文字列展開以外の場合、以下の形式で、 bash はパラメータが設定されているか、空ではないかを調べます。 コロンを省略した場合には設定されているかどうかのみを調べます。

${parameter:-word}

デフォルトの値を使います。 parameter が設定されていないか空文字列であれば、 word を展開したものに置換されます。そうでなければ、 parameter の値に置換されます。

${parameter:=word}

デフォルトの値を代入します。 parameter が設定されていないか空文字列であれば、 word を展開したものが parameter に代入されます。それから parameter の値への置換が行われます。 位置パラメータや特殊パラメータへの代入をこのように行うことはできません。

${parameter:?word}

空文字列または設定されていない場合にエラーを表示します。 parameter が空文字列または設定されていない場合、word を展開したもの (word がなければ パラメータが空文字列または設定されていないことを示すメッセージ) が標準エラー出力に出力されます。シェルが対話的でなければ、 シェルは終了します。パラメータに空文字列以外が設定されていれば、 parameter の値への置換が行われます。

${parameter:+word}

別の値を使用します。 parameter が空文字列または設定されていなければ、空文字列に置換されます。 そうでなければ word を展開したものに置換されます。

${parameter:offset}
${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 が添字に @ または * の付いた配列変数の場合は、配列の要素のそれぞれに大文字小文字の変換が適用され、 結果はリストに展開されます。

コマンド置換

コマンド置換 (command substitution) を用いると、 コマンド名をコマンドの出力で置き換えられます。 コマンド置換には以下の 2 つの形式があります:

$(command) または `command`

bash は command を実行し、 command の標準出力でコマンド置換の部分を置き換えます。 この際、末尾の改行文字は削除されます。 文字列の途中にある改行文字は削除されませんが、 単語分割の際に削除されることがあります。 コマンド置換 $(cat file) は、同じ意味を持ち、 しかも高速な $(< file) に置き換え可能です。

算術式展開

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

$*1

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

使用頻度が高いのは前方一致,後方一致,文字列置換とかかな.

以上,長文失礼しました.

*1:expression