Dies funktioniert in Bash:
touch a b c
echo !(a)
Wenn ich das obige Skript in zsh (mit kshglob
on) ausführe , beschwert es sich:
zsh: number expected
Wenn ich hinzufügen , |
nach a
, es funktioniert:
echo !(a|)
Warum?
In diesem Fall kommt es zu Konflikten mit Bare-Glob-Qualifikatoren, da diese am Ende des Musters stehen. *(a1)
wird als die Dateien verwendet, auf die am letzten Tag zuletzt zugegriffen wurde. (a1)
wird als Glob-Qualifier behandelt. In Ihrem !(a)
Fall beschwert sich zsh über die fehlende Anzahl von Tagen nach dem a
Glob-Qualifikationsmerkmal (hier angewendet auf die aufgerufene Datei !
).
In zsh
Globs wird die (...)
Gruppierung hauptsächlich für den (foo|bar)
Wechsel verwendet. Das Hinzufügen von a |
ist daher eine dokumentierte Methode, um sicherzustellen, dass ein Trailing (...)
nicht als Glob-Qualifizierer behandelt wird.
Eine andere dokumentierte Alternative besteht darin, die Klammer ( !((a))
) zu verdoppeln, oder Sie können ein leeres Glob-Qualifikationsmerkmal (wie !(a)(-)
) hinzufügen .
Um diese Mehrdeutigkeit vollständig zu beseitigen, kann man die bare_glob_qual
Option ( set +o bareglobqual
) deaktivieren, wonach Glob-Qualifizierer mit der extendedglob
(#q...)
Syntax ( *(#qa1)
hier) geschrieben werden müssen.
Die kshglob
Option ( 1998 hinzugefügt , ungefähr zur gleichen Zeit bash
hinzugefügt, extglob
obwohl bash vorher keinen erweiterten Glob hatte) ist hauptsächlich für den ksh
Emulationsmodus ( emulate ksh
) vorhanden, um Skripte zsh
ausführen zu können ksh
, wo kshglob
aktiviert und bareglobqual
deaktiviert ist. Bei der ersten Einführung mussten Sie nach dem Aktivieren kshglob
Glob-Qualifikationsmerkmale angeben -(...)
, um diese Art von Konflikten zu vermeiden. Dies führte jedoch zu zu viel Verwirrung und widersprach der @-(...)
Syntax von ksh93
, (#q...)
und bareglobqual
Optionen wurden später eingeführt.
zsh
Benutzer bevorzugen im Allgemeinen die erweiterten erweiterten glob ( set -o extendedglob
) - Operatoren von zsh, die (für die meisten) einfacher einzugeben und leistungsfähiger sind (als die ksh88-Operatoren, die mit aktiviert kshglob
sind bash -O extglob
).
Zum Beispiel !(foo)
würde geschrieben werden ^foo
. Das !(foo|)bar
Äquivalent wäre jedoch länger wie (^(foo|))bar
.
Andere ksh88 -> zsh Übersetzungen:
*(x)
-> x#
+(x)
-> x##
@(x|y)
-> x|y
?(x)
-> (x|)
Einige ksh93 -> zsh Übersetzungen:
~(i:x)
-> (#i)x
(Groß- und Kleinschreibung nicht berücksichtigen)~(N)x
-> x(N)
(nullglob, ursprünglich in zsh){1,5}(x)
-> x(#c1,5)
@(foo&bar)
-> foo~^bar
oder^(^foo|^bar)
Einige nur gefunden in zsh
:
<1-23>
(Bereich von Dezimalzahlen)pattern~except
pattern(glob-qualifier)
(das Killer-Feature von zsh globs)(pattern/)#
(Jede Ebene von Unterverzeichnissen, die mit übereinstimmen pattern
; die **/
vereinfachte Version von (*/)#
wurde kürzlich auch zu ksh93 und bash hinzugefügt.)***/*
(rekursives Globbing nach Symlinks).(#a1)foobar
(ungefähre Übereinstimmung, die einige Fehler zulässt, hier 1)