Bashのブレース展開のルール

Sat Feb 10 17:20:17 JST 2024 (modified: Sat Feb 10 17:25:48 JST 2024)
views: 841, keywords:bash

 このまえ悩みまくってましたが、やっと解決したようなのでまとめます。その前に宣伝ですが、シェル芸勉強会やるのできてくださーい。

基本ルール

 文字列を左から右に読んでいって、{があったら、次のルールで{がブレース展開の開始の括弧なのか(OK)、そうでないか(NG)を判別。詳しくないけどLR文法に属すっぽいです。スタックを使うと簡単に実装できます。

  1. そこから右側に読んでいって}を探す。なかったらNG
  2. }があったら、そこから左側に{を探す。
  3. 見つけた{が最初の{でなければ見つけた{から}までをマスクして、1に戻る。
  4. 見つけた{が最初の{で、途中に,があればOK
  5. 見つけた{が最初の{で、4に該当しなければ{だけ残してあとをマスクし、1に戻る。

例1

{{a},b}     #一番左の{が対象
   {マスク,b} #手続き2と3
   OK

例2

a{}},b}            #aの隣の{が対象
   a{マスク},b}      #手続き2と5
   a{マスクマスク,b} #手続き2と5
   OK

例3

{a,b,c{d,e}f,g{h,i{j,k}}}     #一番左の{が対象
   {a,b,cマスクf,g{h,i{j,k}}}
   {a,b,cマスクf,g{h,iマスク}}
   {a,b,cマスクf,gマスク}
   OK

例3

{a,b,c{d,e}f,g{h,i{j,k}}     #一番左の{が対象
   {a,b,cマスクf,g{h,i{j,k}}
   →{a,b,cマスクf,g{h,iマスク}
   →{a,b,cマスクf,gマスク
   NG

例外1(冒頭・ブレース展開直後の{}

 冒頭、あるいはブレース展開直後に{}がある場合、{はブレース展開の開始と 判定されない

$ echo {},a} #最初の{}は文字列扱いでブレース展開が起こらない
   {},a}
   $ echo x{},a} #あたまにxを置くとブレース展開が起こる
   x} xa
   $ echo {a,b}{},a} #うしろの{},a}はブレース展開として扱われない
   a{},a} b{},a}

例外2(手前の$

 手前にエスケープされていない$があれば、なにがあってもブレース展開されない

$ echo ${a,b}  #これは変数とみなされる
   
   $ echo $${a,b} #「$$」と{a,b}のように見えるがブレース展開しない
   6813{a,b}
   $ echo $\${a,b} #エスケープするとブレース展開する
   $$a $$b

参考: https://stackoverflow.com/questions/77850130/bash-parse-of-x-y

現場からは以上です。

ノート   このエントリーをはてなブックマークに追加 
 

prev:Bashのブレース展開のルールの謎 next:日記(〜2024年2月20日)

やり散らかし一覧

記事いろいろ