Bashのブレース展開のルール
Sat Feb 10 17:20:17 JST 2024 (modified: Sat Feb 10 17:25:48 JST 2024)
views: 1516, keywords:bash この記事は最終更新日が1年以上前のものです。
このまえ悩みまくってましたが、やっと解決したようなのでまとめます。その前に宣伝ですが、シェル芸勉強会やるのできてくださーい。
大手町でやります〜
— 上田隆一 (@ryuichiueda) February 9, 2024
jus共催第68回3月2日でございますシェル芸勉強会 https://t.co/7DRG4ygrAb #シェル芸
基本ルール
文字列を左から右に読んでいって、{があったら、次のルールで{がブレース展開の開始の括弧なのか(OK)、そうでないか(NG)を判別。詳しくないけどLR文法に属すっぽいです。スタックを使うと簡単に実装できます。
- そこから右側に読んでいって
}を探す。なかったらNG }があったら、そこから左側に{を探す。- 見つけた
{が最初の{でなければ見つけた{から}までをマスクして、1に戻る。 - 見つけた
{が最初の{で、途中に,があればOK - 見つけた
{が最初の{で、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
現場からは以上です。
ノート
Tweet