ZSH: Rekursives Globbing ohne bestimmte versteckte Verzeichnisse

7

Ich dachte das Glob-Muster:

**/(*|.*)

würde jeden Ordner und jede Datei darstellen, die mit dot ( .) beginnen oder nicht, aber es werden Verzeichnisse im aktuellen Verzeichnis übersprungen, die mit beginnen ..

Was ist das Glob-Muster, das bedeutet:

Jede Datei und jeder Ordner, mit denen .in den aktuellen und tieferen Ordnern begonnen werden kann oder nicht

Außerdem: Wie kann ich einen bestimmten Ordner (oder noch besser ein Glob-Untermuster) von einem rekursiven Glob-Muster wie dem oben genannten ausschließen?

Ich habe Folgendes versucht, um den Ordner .hgvon der aktuellen Ebene auszuschließen (aber andere Ordner einzuschließen, die mit dem .Zeichen beginnen):

**~.hg/*

aber es ging nicht rekursiv in tiefere Verzeichnisse.

Amelio Vazquez-Reina
quelle

Antworten:

10

Der einfachste Weg, um ein Glob-Muster mit Punktdateien abzugleichen, ist die Verwendung des D Glob-Qualifizierers .

**/*(D)

Der Vorrang der ~niedriger ist als /, so **~.hg/*ist **minus die Spiele für .hg/*. **Ist aber nur dann etwas Besonderes, wenn es vor a steht /, also stimmt es hier mit den Dateien im aktuellen Verzeichnis überein. Zum Ausschließen .hgund dessen Inhalt benötigen Sie

**/*~.hg~.hg/*(D)

Beachten Sie, dass zsh das .hgVerzeichnis weiterhin durchläuft , was einige Zeit dauern kann. Dies ist eine Einschränkung von **: Sie können keine Ausschlussliste direkt auf dieser Ebene festlegen.

Gilles 'SO - hör auf böse zu sein'
quelle
4

**/*(D)( (*/)#*(D)Abkürzung für ) enthält Dotfiles und Dotdirs, wie bereits gesagt.

Wenn Sie .hgVerzeichnisse auf allen Ebenen ausschließen möchten , benötigen Sie:

(^.hg/)#^.hg(D)

(Sie benötigen setopt extendedglobfür die ^und #Operatoren)

Wie bereits erwähnt, ~patternwerden Einträge ausgeschlossen (basierend darauf, ob ihre vollständige Erweiterung mit "Muster" übereinstimmt, nachdem die Liste generiert wurde, sodass sie nicht gestoppt wird, um in Unterverzeichnisse abzusteigen).

Stéphane Chazelas
quelle