Bashのブレース展開のルール
Sat Feb 10 17:20:17 JST 2024 (modified: Sat Feb 10 17:25:48 JST 2024)
views: 841, keywords:bash
このまえ悩みまくってましたが、やっと解決したようなのでまとめます。その前に宣伝ですが、シェル芸勉強会やるのできてくださーい。
大手町でやります〜
— 上田隆一 (@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
現場からは以上です。