展開や置換

スポンサーリンク

シェルの単語展開は一般的に次の順番で行われます。

  1. チルダ展開・パラメータ展開・コマンド置換・算術展開を行う
  2. フィールド分割を行う(IFSがnullではない場合)
  3. パス名の展開
  4. クォート(引用符)の削除

フィールド分割はコマンド自体とその引数を別々の要素として認識できるようになるプロセスです。
コマンドの展開後のフィールドについて、展開結果が空になり、クォートがついてない場合はフィールドのリストから削除されます。

スポンサーリンク

チルダ展開

チルダ展開またはチルダ接頭辞は、クォートをつけないで利用します。これは変数HOMEの値(ホームディレクトリの値)に置き換わります。

別のユーザーのホームディレクトリを指定する場合は<tilde>の後にユーザー名を指定します。上の例はユーザー名が空だった場合と見ることができます。
この展開される値をもう少し厳密に説明すると、getpwnam()関数を使用して取得したログイン名に関連付けられた初期作業ディレクトリのパス名に変換されます。

変数に代入する場合は複数のチルダ展開を利用することができます。これは<equals-sign>の後または<colon>の後に使うことができます。
よく利用する例としては変数PATHに代入のときに使われるでしょう。

パラメータ展開

パラメータ展開の形式は以下のようになります。

パラメータ展開のexpressionは形式に一致した'}'までのすべての文字になります。ただし、

  • バックスラッシュの'}'
  • クォートされた'}'
  • 埋め込まれた算術展開・コマンド置換・パラメータ展開に利用された'}'
    はexpressionを決定する際の'}'として扱われません。

単純なパラメータ展開は

になります。この場合、基本的に中括弧はオプションになります。中括弧がオプションにできない場合は

  • 複数桁の位置パラメータ
  • 利用したいパラメータの後にパラメータの名前として解釈できる文字が続いている場合
    になります。

パラメータ展開は次の形式を使用して変更できます。word はチルダ展開、パラメータ展開、コマンド置換、および算術展開が適用されます。

形式説明
${parameter:-[word]}デフォルト値を使用
${parameter:=[word]}デフォルト値の割り当て
${parameter:?[word]}未設定時にエラー
${parameter:+[word]}代替値を使用

上の表のものはコロンなしでも利用できます。その場合はparameterが設定されていない場合のみに適用されます。
コロンがある場合はparameterが設定されていない場合とnullの値で適用されます。

形式説明
${parameter-[word]}デフォルト値を使用
${parameter=[word]}デフォルト値の割り当て
${parameter?[word]}未設定時にエラー
${parameter+[word]}代替値を使用

コロンのあるなしの例

他にも以下のパラメータ展開があります。

形式説明
${#parameter}文字列の長さ
形式説明
${parameter%[word]}最小のサフィックスパターンを削除
${parameter%%[word]}最大のサフィックスパターンを削除
${parameter#[word]}最小のプレフィックスパターンを削除
${parameter##[word]}最大のプレフィックスパターンを削除

パターンの削除の例

最短一致と最長一致の違いの例

文字説明
?任意の一文字
*複数文字の一致に利用
[ ]文字クラス
パターンに利用できる特殊文字

コマンド置換

コマンド置換は以下の形式で利用できます。

または

コマンド置換はコマンドの実行結果に置き換えることができます。
実行結果の末尾にある改行は削除されます。また、末尾以外の改行などはフィールド分割で削除される場合があります。

算術展開

算術展開は、算術式を評価し、その値を代入できる機能になります。
算術展開は以下の形式で利用できます。

このexpressionはダブルクォーテーションで囲んだように扱われます。なので、パラメータ展開やコマンド置換等が行われます。
また、算術展開内の式ではシェル変数をそのまま参照することができます。

未設定の変数やnullの値は0として扱われます。

expressionの数字の先頭に0をつけると8進数に、0xまたは0Xをつけると16進数として扱うことができます。

補足として、結果の数値を8進数や16進数にする方法としてprintfコマンドの'%o'や'%x'のフォーマット文字列があります。