
これ:
$ echo {{a..c},{1..3}}
次を生成します。
a b c 1 2 3
いいですが、説明するのは難しいです。
$ echo {a..c},{1..3}
与えられた
a,1 a,2 a,3 b,1 b,2 b,3 c,1 c,2 c,3
これはどこかに文書化されていますか?これバッシュリファレンスこれに対する言及はありません(たとえそれを使用する例がありますが)。
答え1
さて、一度に一層ずつ解いてみましょう。
X{{a..c},{1..3}}Y
X{a..c}Y
X{1..3}Y
は(存在を通じて)に拡張されるものとして記録されX{A,B}Y
、それ自体は に拡張されるものとして記録されます。XA
XB
A
{a..c}
B
{1..3}
XaY
XbY
XcY
X1Y
X2Y
X3Y
入れ子にできることを文書化する価値があります(最初の項目は入れ子になっ}
ていません)。閉鎖{
例えば、最初のもの)。
私はシェルがこの問題を解決するために選択できると思います。内部にまず、中括弧は各端で順番に次のように動作します}
。
X{{a..c},{1..3}}
X{a,{1..3}}Y
X{b,{1..3}}Y
X{c,{1..3}}Y
(つまり、、where isとis
A{a..c}B
に拡張されます)AaB
AbB
AcB
A
X{
B
,{1..3}Y
X{a,1}Y
X{a,2}Y
X{a,3}Y
X{b,1}Y
X{b,2}Y
X{b,3}Y
X{c,1}Y
X{c,2}Y
X{c,3}Y
XaY
X1Y
XaY
Xa2
...
csh
しかし、私はこれが特により直感的であるか役に立つとは思いません(たとえば、コメントのKevinの例を参照してください)。拡張が実行される順序についてはまだあいまいさがあります。 70年代の拡張と比較して、後で{1..3}
(1995)で形が作られましzsh
た{a..c}
が、その後(2004)でbash
)が作られました。
参考にしてくださいcsh
(最初から2BSD(1979) マニュアルページ)は中括弧拡張が入れ子になる可能性があるという事実を文書化しますが、入れ子になった中括弧拡張がどのように拡張されるかを明示的に指定しません。しかし、あなたはできます。csh
1979年のコードを見てくださいそれがどのように行われたか見てください。ネストを明示的に処理する方法と、外部中括弧から始めて解析する方法を確認してください。
{a..c},{1..3}
とにかく拡張の影響が何であるかよくわかりません。ここで、,
演算子は中括弧で拡張されていないため(中括弧内にないため)、通常の文字として扱われます。
答え2
それは短い答えです。最初の式では、カンマが区切り文字として使用されるため、中括弧の拡張は、2つの入れ子になったサブ式を連結するだけです。 2番目の式では、カンマ自体が単一文字のサブ式として扱われるため、product式ははいフォーム。
あなたが見逃しているのは、支柱の拡張を実行する方法の定義です。以下は3つの参考資料です。
以下は、より詳細な説明です。
この式の結果を比較します。
$ echo {{a..c},{1..3}}
a b c 1 2 3
この式の結果:
$ echo {a..c},{1..3}
a,1 a,2 a,3 b,1 b,2 b,3 c,1 c,2 c,3
説明しにくいと言いましたね。つまり直観にずれるという意味ですね。欠けているのは、中括弧拡張を処理する方法の正式な定義です。あなたは気づいたバッシュマニュアル完全な定義は提供されません。
少し検索しましたが、欠落している(完全で形式的な)定義も見つかりませんでした。それでソースコードを見に行きました。
ソースにはいくつかの有用な説明が含まれています。まず、支柱拡張アルゴリズムの高レベルの概要です。
Basic idea: Segregate the text into 3 sections: preamble (stuff before an open brace), postamble (stuff after the matching close brace) and amble (stuff after preamble, and before postamble). Expand amble, and then tack on the expansions to preamble. Expand postamble, and tack on the expansions to the result so far.
したがって、中括弧拡張マークアップの形式は次のようになります。
<PREAMBLE><AMBLE><POSTAMBLE>
拡張の主なエントリポイントは、brace_expand
次のように説明される関数です。
Return an array of strings; the brace expansion of TEXT.
したがって、brace_expand
関数は中括弧拡張式を表す文字列を取得し、拡張文字列の配列を返します。
これら 2 つの観察を組み合わせると、序文が文字列リストに展開され、各文字列が前文にリンクされていることがわかります。その後、ポストアンブルは文字列リストに展開され、ポストアンブルリストの各文字列はプリアンブル/プリアンブルリストの各文字列に連結されます(つまり、2つのリストの積を形成します)。ただし、これはプリアンブルとポストアンブルの処理方法については説明しません。幸いなことに、これについてのレビューもあります。この同期コードは、関数expand_amble
定義の前に次の注釈を付けた関数によって処理されます。
Expand the text found inside of braces. We simply try to split the text at BRACE_ARG_SEPARATORs into separate strings. We then brace expand each slot which needs it, until there are no more slots which need it.
コードの他の部分では、BRACE_ARG_SEPARATORがコンマで定義されていることがわかります。これは、ambleがカンマで区切られた文字列のリストであり、その一部は中括弧で拡張された式である可能性があることを明らかに示しています。その後、これらの文字列は配列で構成されます。最後に、expand_amble
afterを呼び出した後、事後brace_expand
同期コードで関数が再帰的に呼び出されることも確認できます。これはアルゴリズムの完全な説明を提供します。
この結果を確認するいくつかの異なる(非公式)参考資料があります。
参考としてを参照してくださいバッシュハッカーウィキ。このセクションは次のとおりです。結合とネストあなたの質問に正確に答えるわけではありませんが、ページには中括弧拡張の構文/構文があり、あなたの質問に答えると思います。構文は次のパターンで提供されます。
{string1,string2,...,stringN}
{<START>..<END>}
<PREAMBLE>{........}
{........}<POSTSCRIPT>
<PREAMBLE>{........}<POSTSCRIPT>
解析の説明は次のとおりです。
中括弧拡張は、ランダムな文字列を生成するために使用されます。指定された文字列は生成に使用されます。可能なすべての組み合わせオプションで、周辺の序文と後期スクリプトが含まれます。
その他の注意事項については、以下を確認してください。Bash初心者ガイド、これには以下が含まれます。
Brace expansion is a mechanism by which arbitrary strings may be generated. Patterns to be brace-expanded take the form of an optional PREAMBLE, followed by a series of comma-separated strings between a pair of braces, followed by an optional POSTSCRIPT. The preamble is prefixed to each string contained within the braces, and the postscript is then appended to each resulting string, expanding left to right.
したがって、中括弧拡張式を解析するために左から右に移動し、各式を拡張して連続製品を形成します(文字列連結操作とは対照的に)。
では、最初の表現を考えてみましょう。
{{a..c},{1..3}}
Bash Hacker's Wiki言語では、これは最初の形式と一致します。
{string1,string2,...,stringN}
ここでN=2
、string1={a..c}
およびstring2={1..3}
- 内部中括弧拡張を最初に実行し、各拡張は次の形式を持ちます{<START>..<END>}
。あるいは、これは序文のみを含む中括弧拡張表現(序文または後文なし)と言うことができます。 ambleはカンマ区切りのリストなので、一度に1スロットずつリストを確認し、必要に応じて追加の拡張を実行します。隣接式がないため(カンマを区切り文字として使用する)、積は形成されません。
次に、2番目の表現を見てみましょう。
{a..c},{1..3}
Bash Hacker's Wikiの言語では、この表現は次の形式と一致します。
{........}<POSTSCRIPT>
ここでpostscriptはサブ式です,{1..3}
。あるいは、この表現には序文({a..c}
)と後文()があると言うことができます,{1..3}
。プリアンブルはリストに展開されa b c
、各リストはポストアンブル拡張の各文字列に関連付けられます。ポストアンブルは再帰的に処理されます。プリアンブルは,
、プリアンブルはです{1..3}
。これはリストに拡張されました,1 ,2 ,3
。a b c
次に、2つのリストを,1 ,2 ,3
組み合わせて製品リストを形成しますa,1 a,2 a,3 b,1 b,2 b,3 c,1 c,2 c,3
。
これらの式がどのように解析されるかを疑似代数的に説明することが役に立つかもしれません。ここで、角括弧「[]」は配列を表し、「+」は配列連結を表し、「*」はデカルト積(連結とは反対)を表します。
最初の式を拡張する方法は次のとおりです(1行に1ステップ)。
{{a..c},{1..3}}
{a..c} + {1..3}
[a b c] + [1 2 3]
a b c 1 2 3
2番目の式を拡張する方法は次のとおりです。
{a..c},{1..3}
{a..c} * ,{1..3}
[a b c] * [,1 ,2 ,3]
a,1 a,2 a,3 b,1 b,2 b,3 c,1 c,2 c,3
答え3
私の理解は次のとおりです。
内部中かっこは常にそのように最初に解析されます。
{{a..c},{1..3}}
入力する
{a,b,c,1,2,3}
,
中かっこ内にあるため、中かっこ要素のみを分離します。
しかし、この場合
{a..c},{1..3}
つまり、これは,
中括弧内にはありません。つまり、中括弧が両側に揃えるようにする一般的な文字です。