Was ist der Unterschied zwischen a[bc]d
und a{b,c}d
? Warum nutzen Menschen, a{b,c}d
wenn es sie schon gibt a[bc]d
?
brace-expansion
pattern-matching
Weijun Zhou
quelle
quelle
command a[bc]d
?ls
versuchen und Sie immer nur einzelne Zeichen versuchen, scheinen sie gleich zu funktionieren.Antworten:
Die beiden sind sehr unterschiedlich.
a[bc]d
ist ein Dateinamenmuster (in anderen Shells alsfish
). Es wird auf die beiden Dateinamen erweitertabd
undacd
ob dies die Namen der im aktuellen Verzeichnis vorhandenen Dateien sind.Der
[...]
Teil ist ein Ausdruck in eckigen Klammern, der mit einem der aufgelisteten Zeichen übereinstimmt (oder Elemente sortiert, wenn Bereiche enthalten sind). Um das Muster abzugleichen, mussa[bc]d
das Zeichen zwischen den Zeichenfolgena
undd
in einem Dateinamen entweder ab
oder a seinc
.Wenn es
abd
existiert, aberacd
nicht, dann würde es nur expandierenabd
und umgekehrt.Wenn weder
abd
, nochacd
vorhanden ist , in Abhängigkeit von der Schale und den Optionen, würde es einen Fehler (Original Unix auslösensh
,(t)csh
,zsh
,fish
,bash -O failglob
) und möglicherweise den Shell verlassen, oder lassen Sie das Muster unexpanded¹ (Bourne-like undrc
-artigen Schalen) oder erweitern , um nichts (bash/zsh/yash -o nullglob
einige ältere Versionen vonfish
Original-Unixsh
und(t)csh
wenn es andere übereinstimmende Globs im selben Befehl gibt).a{b,c}d
ist eine Klammererweiterung (in Schalen, die diese unterstützen). Es wird auf die beiden Saitenabd
und erweitertacd
.Der
{...}
Teil ist eine durch Kommas getrennte Menge von Zeichenfolgen (in diesem Beispiel; in einigen Shell-Fällen kann es sich auch um einen Bereich wiea..k
oder20..25
oder einen fortgeschritteneren wie00..20..2
oder handeln0..20..2%02d
). Die Erweiterung wird berechnet, indem jede dieser Zeichenfolgen mit der Flanke kombiniert wird Streichera
undd
. Diese Zeichenfolgen können länger als ein einzelnes Zeichen sein und können auch selbst Klammererweiterungen sein.Die Erweiterung erfolgt unabhängig davon, ob diese Zeichenfolgen vorhandenen Dateinamen entsprechen oder nicht.
Wenn Sie Zeichenfolgen erstellen, verwenden Sie eine geschweifte Klammer. Wenn Sie mit Dateinamen übereinstimmen, verwenden Sie ein Dateinamenmuster.
¹ In diesem speziellen Fall kann es vorkommen,
a[bc]d
dass es sich um den Namen einer vorhandenen Datei handelt, weshalb es möglicherweise gefährlich ist, Dinge wie dieserm -f ./*.[ch]
in Shells zu verwenden, und diesrm -f ./*.{c,h}
ist weniger problematisch.quelle
a{b,c}d
dieb
undc
-Teile keine einzelnen Buchstaben sein müssen. zBex{ten,ci}sion
. Wobeiex[tenci]sion
oder was auch immer nur mit einem dieser Buchstaben übereinstimmt .a[bc]d
ist eine Mustererkennung und Teil des POSIX-Standards. In POSIX wird dies als "Musterklammerausdruck" eingeführt. Dies ist in Abschnitt 2.13 des Handbuchs dokumentiertIn Abschnitt 2.13.3 wird auch etwas erwähnt, das sich anders verhält als man es von regulären Ausdrücken erwartet, wenn es für die Dateinamenerweiterung verwendet wird (Hervorhebung von mir).
a{b,c}d
ist eine Klammererweiterung , sie ist nicht in der Spezifikation von POSIX enthalten. Hier ist der entsprechende Teil aus dem Bash- Handbuch (Hervorhebung von mir):Laut dem Kommentar von @mosvy ist dies zuerst von aufgetaucht,
csh
aber das Verhalten inbash
unterscheidet sich voncsh
und von anderen Shells. Diese Art der Strebendehnung ist auch in vorhandenglob(3)
.Es gibt eine andere Art der Klammererweiterung
{a..z}
, die erst nachbash
3.0 erschien, und inbash
4.0 wurden weitere hinzugefügt .Führen Sie in einer Shell, in der das Globbing aktiviert ist, in einem leeren Ordner das folgende Ergebnis aus
Wenn Sie sich in einer interaktiven Shell befinden und beide zutreffen, haben Sie als Antwort auf den Kommentar von @ Jesse_b
a[bc]d
weniger Probleme bei der Eingabe. Zum Beispielgrep pattern [ab][12].txt
.quelle
csh
, lange bevorbash
. Es ist auch in der Bibliotheksfunktion glob (3) enthalten. Der Unterschied besteht darin, dassbash
es vor anderen Erweiterungen ausgeführt wird: Esa=A; ab=A/B; ac=A/C; echo $a{b,c}
funktioniert in bash anders als in jeder anderen Shell.