Jaka jest różnica między a[bc]d
i a{b,c}d
? Dlaczego ludzie używają, a{b,c}d
gdy już jest a[bc]d
?
brace-expansion
pattern-matching
Weijun Zhou
źródło
źródło
command a[bc]d
?ls
i kiedykolwiek spróbujesz tylko pojedynczych znaków, będą one wyglądać tak samo.Odpowiedzi:
Te dwa są całkiem różne.
a[bc]d
to wzorzec nazwy pliku (w powłokach innych niżfish
). Rozwinie się do dwóch nazw plikówabd
iacd
jeśli są to nazwy istniejących plików w bieżącym katalogu.[...]
Część jest nawias wyrażenie, które dopasowuje pojedynczy znak z tych wymienionych (lub elementy zestawiania gdy zakresy są w zestawie). Pasujące do wzorcaa[bc]d
, postać między strunamia
id
w pliku musi być albob
alboc
.Jeśli
abd
istnieje, aleacd
nie istnieje, rozszerzyłby się tylkoabd
i odwrotnie.Jeśli nie
abd
, nieacd
istnieją, w zależności od powłoki i opcji, to spowodowałoby błąd (oryginalna Unixsh
,(t)csh
,zsh
,fish
,bash -O failglob
) i ewentualnie wyjść z powłoki lub opuszczają unexpanded¹ wzoru (Bourne'a jak irc
-jak muszle) lub rozwinąć się nic (bash/zsh/yash -o nullglob
niektóre starsze wersjefish
oryginalnego Uniksash
i(t)csh
jeśli w tym samym poleceniu są inne pasujące globusy).a{b,c}d
jest rozszerzeniem nawiasów klamrowych (w powłokach, które je obsługują). Rozwinie się do dwóch ciągówabd
iacd
.{...}
Część jest przecinkami ograniczony zestaw łańcuchów (w tym przykładzie, w niektórych powłoki, mogą być też szereg takich jaka..k
lub20..25
lub więcej zaawansowanych, jak00..20..2
i0..20..2%02d
) i rozszerzenie jest obliczana przez łączenie każdego z tych łańcuchów z flankującymi ciągia
id
. Te ciągi znaków mogą być dłuższe niż pojedynczy znak i same mogą być rozszerzeniami nawiasów klamrowych.Rozwijanie odbywa się niezależnie od tego, czy te ciągi odpowiadają istniejącym nazwom plików, czy nie.
Jeśli konstruujesz ciągi, użyj rozwinięcia nawiasu. Jeśli pasujesz nazwy plików, użyj wzorca nazwy pliku.
¹ W tym konkretnym przypadku
a[bc]d
może się zdarzyć, że jest to nazwa istniejącego pliku, dlatego potencjalnie niebezpieczne jest używanie rzeczy takich jakrm -f ./*.[ch]
w tych powłokach irm -f ./*.{c,h}
jest to mniejszy problem.źródło
a{b,c}d
, gdyb
ic
części nie muszą być pojedyncze litery; npex{ten,ci}sion
. Chociażex[tenci]sion
lub cokolwiek będzie pasować tylko do jednej z tych liter.a[bc]d
jest zgodny ze wzorami i jest częścią standardu POSIX. W POSIX jest to wprowadzane jako „wyrażenie w nawiasie wzorcowym”. Jest to udokumentowane w sekcji 2.13 instrukcjiSekcja 2.13.3 wspomina także o tym, że zachowuje się inaczej niż można by się spodziewać po zwykłych wyrażeniach regularnych, gdy jest on używany do rozwijania nazw plików (moje podkreślenie)
a{b,c}d
jest rozszerzeniem nawiasów klamrowych , nie znajduje się w specyfikacji POSIX. Oto odpowiednia część podręcznika bash (podkreślenie przeze mnie):Zgodnie z komentarzem @mosvy, ten pierwszy pojawił się z,
csh
ale zachowanie w nimbash
jest innecsh
i inne powłoki. Ten typ rozszerzenia nawiasów jest również obecny wglob(3)
.Istnieje inny rodzaj rozszerzenia nawiasów klamrowych,
{a..z}
który pojawił się dopiero po wersjibash
3.0, a więcej dodano w wersjibash
4.0.W powłoce, w której globbing jest włączony, wykonaj w pustym folderze, zwracany jest następujący wynik
W odpowiedzi na komentarz @ Jesse_b, jeśli jesteś w interaktywnej powłoce i oba mają zastosowanie,
a[bc]d
to mniej kłopotów z pisaniem. Na przykładgrep pattern [ab][12].txt
.źródło
csh
długo przedtembash
. Jest także obecny w funkcji biblioteki glob (3). Różnica polega na tym,bash
że jest wykonywana przed innymi rozszerzeniami:a=A; ab=A/B; ac=A/C; echo $a{b,c}
będzie działać w bash inaczej niż jakakolwiek inna powłoka.