find(für die Prädikate -name/ -pathstandard) verwendet Platzhaltermuster wie Globs (beachten Sie, dass dies {a,b}kein Glob-Operator ist; nach der Erweiterung erhalten Sie zwei Globs). Der Hauptunterschied ist die Behandlung von Schrägstrichen (und Punktdateien und Verzeichnissen, die nicht speziell behandelt werden find). *in Globs werden nicht mehrere Verzeichnisse überspannt. */*/*Dadurch werden bis zu 2 Verzeichnisebenen aufgelistet. Das Hinzufügen von a entspricht -path './*/*/*'allen Dateien, die mindestens 3 Ebenen tief sind, und hört nicht auf, findden Inhalt eines Verzeichnisses in irgendeiner Tiefe aufzulisten.
Für diesen besonderen
./foo*bar/quux[A-Z]{.bak,}/pic[0-9][0-9][0-9][0-9]?.jpg
Ein paar Globs, es ist einfach zu übersetzen. Sie möchten Verzeichnisse in Tiefe 3, damit Sie Folgendes verwenden können:
find . -mindepth 3 -maxdepth 3 \
\( -path './foo*bar/quux[A-Z].bak/pic[0-9][0-9][0-9][0-9]?.jpg' -o \
-path './foo*bar/quux[A-Z]/pic[0-9][0-9][0-9][0-9]?.jpg' \) \
-exec cmd {} +
(oder -depth 3mit einigen findImplementierungen). Oder POSIXly:
find . -path './*/*/*' -prune \
\( -path './foo*bar/quux[A-Z].bak/pic[0-9][0-9][0-9][0-9]?.jpg' -o \
-path './foo*bar/quux[A-Z]/pic[0-9][0-9][0-9][0-9]?.jpg' \) \
-exec cmd {} +
Welches würde garantieren, dass diese *und ?nicht /Zeichen übereinstimmen konnten .
(Im findGegensatz zu Globs würde der Inhalt anderer Verzeichnisse als foo*barder im aktuellen Verzeichnis¹ gelesen und die Liste der Dateien nicht sortiert. Wenn wir jedoch das Problem außer Acht lassen, dass das, was übereinstimmt, [A-Z]oder das Verhalten von */ ?in Bezug auf ungültige Zeichen ist nicht spezifiziert, würden Sie die gleiche Liste von Dateien erhalten).
Wie @muru gezeigt hat , muss auf keinen Fall darauf zurückgegriffen werden, findwenn nur die Liste der Dateien in mehrere Läufe aufgeteilt werden soll, um das Limit des execve()Systemaufrufs zu umgehen. Einige Shells wie zsh(mit zargs) oder ksh93(mit command -x) haben sogar eine eingebaute Unterstützung dafür.
Mit zsh(deren Globs auch das Äquivalent -type fund die meisten anderen findPrädikate haben), zum Beispiel:
autoload zargs # if not already in ~/.zshrc
zargs ./foo*bar/quux[A-Z](|.bak)/pic[0-9][0-9][0-9][0-9]?.jpg(.) -- cmd
( (|.bak)Ist ein glob Betreiber entgegen {,.bak}, das (.)glob Qualifier die äquivalent ist find‚s -type f, fügen Sie oNdort mit der Sortierung wie zu überspringen find, Dschließen Punkt-Dateien (gilt nicht für diesen glob))
¹ Um findden Verzeichnisbaum wie Globs zu crawlen, benötigen Sie Folgendes:
find . ! -name . \( \
\( -path './*/*' -o -name 'foo*bar' -o -prune \) \
-path './*/*/*' -prune -name 'pic[0-9][0-9][0-9][0-9]?.jpg' -exec cmd {} + -o \
\( ! -path './*/*' -o -name 'quux[A-Z]' -o -name 'quux[A-Z].bak' -o -prune \) \)
Das heißt beschneiden alle Verzeichnisse auf Stufe 1 bis auf die foo*bareine, und alle auf Stufe 2 , mit Ausnahme der quux[A-Z]oder quux[A-Z].bakEinsen, und wählen Sie die pic...diejenigen auf der Ebene 3 (und beschneiden alle Verzeichnisse auf dieser Ebene).
-pathoder zu verwenden-ipath.find . -path './foo*bar/quux[A-Z]/pic[0-9][0-9][0-9][0-9]?.jpg'sollte funktionieren - außer dass es passt/fooz/blah/bar/quuxA/pic1234d.jpg. Wird das ein Problem sein?