İşte kısa cevap. İlk ifadede virgül ayırıcı olarak kullanılır, bu nedenle küme ayracı genişlemesi sadece iç içe iki alt ifadenin birleşimidir. Ürün ifadeleri, ikinci ifadede virgül kendisi, tek bir karakter alt ifade olarak kabul edilir olan oluşturulur.
Eksik olan parantez açılımlarının nasıl yapıldığıdır. İşte üç referans:
Daha ayrıntılı bir açıklama aşağıdadır.
Bu ifadenin sonucunu karşılaştırdınız:
$ echo {{a..c},{1..3}}
a b c 1 2 3
bu ifadenin sonucuna:
$ echo {a..c},{1..3}
a,1 a,2 a,3 b,1 b,2 b,3 c,1 c,2 c,3
Bunun açıklanması zor, yani bunun sezgisel olduğunu söylüyorsunuz. Eksik olan, ayraç genişlemelerinin nasıl işlendiğinin resmi bir tanımıdır. Bash El Kitabının tam bir tanım sağlamadığını unutmayın .
Biraz aradım ama eksik (tam, resmi) tanımı da bulamadım. Bu yüzden kaynak koduna gittim:
Kaynak birkaç faydalı yorum içeriyor. Birincisi, küme ayracı genişletme algoritmasına üst düzey bir genel bakış:
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.
Dolayısıyla, küme ayracı genişletme belirtecinin biçimi şöyledir:
<PREAMBLE><AMBLE><POSTAMBLE>
Genişlemeye ana giriş noktası, brace_expand
şu şekilde açıklanan bir işlevdir :
Return an array of strings; the brace expansion of TEXT.
Böylece brace_expand
işlev, küme ayracı genişletme ifadesini temsil eden bir dize alır ve genişletilmiş dizelerin dizisini döndürür.
Bu iki gözlemin bir araya gelmesiyle, amble'in her biri giriş ekinde birleştirilen bir dizeler listesine genişletildiğini görüyoruz. Daha sonra postamble bir dize listesine genişletilir ve postamble listesindeki her dize, önsöz / amble listesindeki her bir dizeye birleştirilir (yani, iki listenin ürünü oluşturulur). Ancak bu, amble ve postamble'ın nasıl işlendiğini açıklamaz. Neyse ki bunu da açıklayan bir yorum var. Amble, expand_amble
tanımının önünde aşağıdaki yorum olan bir işlev tarafından işlenir :
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.
Kodun başka bir yerinde BRACE_ARG_SEPARATOR'un virgül olarak tanımlandığını görüyoruz. Bu, amble'ın, bazıları da küme ayracı genişletme ifadeleri de olabilen virgülle ayrılmış bir dizeler listesi olduğunu açıkça ortaya koymaktadır. Bu dizeler daha sonra tek bir dizi oluşturur. Son olarak, biz de sonra görebilirsiniz expand_amble
denir brace_expand
işlevi daha sonra postamble üzerinde ardışık olarak adlandırılır. Bu bize algoritmanın tam bir tanımını verir.
Bu bulguyu doğrulayan başka (gayri resmi) referanslar da vardır.
Bir referans için Bash Hackers Wiki'sine göz atın . Birleştirme ve yerleştirme bölümü sorununuzu tam olarak ele almıyor, ancak sayfa sorunuzu cevapladığını düşündüğüm söz dizimi genişlemesi sözdizimi / dilbilgisi veriyor. Sözdizimi aşağıdaki kalıplarla verilir:
{string1,string2,...,stringN}
{<START>..<END>}
<PREAMBLE>{........}
{........}<POSTSCRIPT>
<PREAMBLE>{........}<POSTSCRIPT>
Ayrıştırma şu şekilde açıklanır:
Brace genişletmesi rastgele dizeler oluşturmak için kullanılır. Belirtilen dizeler , isteğe bağlı çevreleyen önsözler ve postscriptler ile tüm olası kombinasyonları oluşturmak için kullanılır .
Başka bir referans için, aşağıdakileri içeren Bash Acemi Rehberine göz atın :
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.
Böylece küme ayracı genişleme ifadelerini ayrıştırmak için soldan sağa doğru gidip her bir ifadeyi genişletir ve birbirini takip eden ürünler oluştururuz (dizi-birleştirme işlemiyle ilgili olarak).
Şimdi ilk ifadenizi düşünelim:
{{a..c},{1..3}}
Bash Hacker'ın Wiki'sinde, bu ilk formla eşleşir:
{string1,string2,...,stringN}
Burada N=2
, string1={a..c}
ve string2={1..3}
- iç bağ açılımları önce gerçekleştirilen ve her biri yapıdadır {<START>..<END>}
. Alternatif olarak, bunun sadece bir amble (önsöz veya postamble içermeyen) içeren bir küme ayracı genişletme ifadesi olduğunu söyleyebiliriz. Amble, virgülle ayrılmış bir listedir, bu nedenle listeden birer birer yuvaya gider ve gerektiğinde ek genişletmeler yaparız. Hiçbir ürün oluşmaz, çünkü bitişik ifadeler yoktur (virgül ayırıcı olarak kullanılır).
Şimdi ikinci ifadenize bakalım:
{a..c},{1..3}
Bash Hacker'ın Wiki'sinde, bu ifade şu formla eşleşir:
{........}<POSTSCRIPT>
burada postscript alt ifadedir ,{1..3}
. Alternatif olarak, bu ifadenin bir amble ( {a..c}
) ve bir postamble ( ,{1..3}
) olduğunu söyleyebiliriz . Amble, listeye genişletilir a b c
ve daha sonra bunların her biri, postamble'ın genişlemesindeki dizelerin her biri ile birleştirilir. Postamble özyinelemeli olarak işlenir: bir önsözü ,
ve bir özü vardır {1..3}
. Bu listeye genişletilir ,1 ,2 ,3
. İki liste a b c
ve ,1 ,2 ,3
daha sonra ürün listesini oluşturmak üzere birleştirilir a,1 a,2 a,3 b,1 b,2 b,3 c,1 c,2 c,3
.
Bu ifadelerin nasıl ayrıştırıldığına dair psuedo-cebirsel bir açıklama vermek yardımcı olabilir, burada köşeli parantez "[]" dizileri gösterir, "+" dizi birleştirme anlamına gelir ve "*" Kartezyen ürünü (birleştirme ile ilgili olarak) belirtir.
İlk ifade şu şekilde genişletilir (satır başına bir adım):
{{a..c},{1..3}}
{a..c} + {1..3}
[a b c] + [1 2 3]
a b c 1 2 3
İkinci ifade şu şekilde genişletilir:
{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