bash
wurde ursprünglich in den späten 80ern als Teilklon ksh
mit einigen interaktiven Funktionen von csh / tcsh entworfen.
Die Ursprünge des Globbing müssen in den früheren Muscheln liegen, auf denen es aufbaut.
ksh
selbst ist eine Erweiterung der Bourne-Shell. Die Bourne-Shell selbst (erstmals 1979 in Unix V7 veröffentlicht) war eine saubere Implementierung von Grund auf neu, weicht jedoch nicht vollständig von der Thompson-Shell (der Shell von V1 -> V6) ab und enthält Funktionen der Mashey-Shell.
Insbesondere wurden Befehlsargumente immer noch durch Leerzeichen getrennt, |
war jetzt der neue Pipe-Operator, ^
wurde aber weiterhin als Alternative unterstützt (und erklärt auch, warum Sie dies tun [!a-z]
und nicht [^a-z]
), $1
war immer noch das erste Argument für ein Skript und Backslash war immer noch das Escape-Zeichen . So viele der regulären Ausdrucksoperatoren ( ^\|$
) haben in der Shell eine eigene Bedeutung.
Die Thompson-Shell stützte sich beim Globbing auf ein externes Dienstprogramm. Wenn sh
nicht notiert gefunden *
, [
oder ?
s in dem Befehl, würde es den Befehl durchlaufen glob
.
rm *.txt
würde am Ende glob laufen als:
["glob", "rm", "*.txt"]
und glob würde am Ende rm
mit der Liste der Dateien ausgeführt, die diesem Muster entsprechen.
grep a.\*b *.txt
würde laufen glob
als:
["glob", "grep", "a.\252b", "*.txt"]
Das *
Obige wurde zitiert, indem das 8. Bit für dieses Zeichen gesetzt wurde, um zu verhindern glob
, dass es als Platzhalter behandelt wird. glob
würde dann dieses Bit vor dem Aufruf entfernen grep
.
Um das Äquivalent mit regulären Ausdrücken zu machen, wäre das gewesen:
regexp rm '\.txt$'
Oder:
regexp rm '^[^.].*\.txt$'
Punktdateien ausschließen.
Die Notwendigkeit, den Operatoren zu entkommen, da sie als Shell-Sonderzeichen .
fungieren , und die Tatsache, dass in Dateinamen häufig ein regulärer Ausdrucksoperator verwendet wird, macht es für Anfänger nicht sehr angemessen, Dateinamen abzugleichen und kompliziert. In den meisten Fällen benötigen Sie lediglich Platzhalter , die entweder ein ( ?
) oder eine beliebige Anzahl ( *
) von Zeichen ersetzen können .
Jetzt haben verschiedene Shells verschiedene Globbing-Operatoren hinzugefügt. Heutzutage sind die ksh- und zsh-Globs (und in gewissem Maße bash -O extglob
eine Teilmenge von ksh-Globs) funktional äquivalent zu regulären Ausdrücken mit einer Syntax, deren Verwendung mit Dateinamen und der aktuellen Shell-Syntax weniger umständlich ist. In zsh
(mit Extendedglob-Erweiterung) können Sie beispielsweise Folgendes tun:
echo a#.txt
wenn Sie (unwahrscheinlich) mit Dateinamen übereinstimmen möchten, die aus Sequenzen von a
gefolgt von bestehen .txt
. Einfacher als echo (^a*\.txt$)
(hier die Verwendung von geschweiften Klammern, um die Regex-Operatoren von den Shell-Operatoren zu isolieren, die eine Möglichkeit gewesen sein könnten, wie Shells damit umgehen könnten).
echo (foo|bar|<1-20>).(#i)mpg
Für mpg-Dateien (ohne Berücksichtigung der Groß- und Kleinschreibung), deren Basisname foo, bar oder eine Dezimalzahl von 1 bis 20 ist ...
ksh93
Jetzt können auch reguläre Ausdrücke (einfach, erweitert, perlartig oder "erweitert") in die Globs integriert werden (obwohl dies ziemlich fehlerhaft ist) und es wird sogar ein Tool zum Konvertieren zwischen glob und regulärem Ausdruck ( printf %R
, printf %P
) bereitgestellt :
echo ~(Ei:.*\.txt)
zu Spiel (nicht verborgen) txt - Dateien mit E regulären Ausdrücken Xtended, Case- i nsensitively.
rm -- ^[^.].*\.txt$
stattrm -- *.txt
?