Ich habe kürzlich festgestellt, dass die POSIX-Spezifikationen fürfind
nicht die -maxdepth
Primärdaten enthalten.
Für diejenigen, die nicht damit vertraut sind, besteht der Zweck des -maxdepth
primären darin, zu begrenzen, wie viele Ebenen tief find
abgesenkt werden. -maxdepth 0
führt dazu, dass nur Befehlszeilenargumente verarbeitet werden. -maxdepth 1
würde nur Ergebnisse direkt in den Kommandozeilenargumenten behandeln, etc.
Wie kann ich -maxdepth
mit nur von POSIX angegebenen Optionen und Tools das dem Nicht-POSIX- Primärsystem entsprechende Verhalten erzielen?
(Hinweis: Natürlich kann ich das Äquivalent dazu erhalten, -maxdepth 0
indem ich nur -prune
den ersten Operanden verwende, aber das erstreckt sich nicht auf andere Tiefen.)
-depth -2
,-depth 1
... Ansatz könnte als besser angesehen werden als GNU's-maxdepth
/-mindepth
-maxdepth
/-mindepth
gibt es sinnvolle Alternativen (beachten Sie, dass-path
es sich um eine neue Ergänzung zu POSIX handelt). Die Alternativen für-timexy
oder-mtime -3m
(oder-mmin -3
) sind viel umständlicher. Manche mögen-execdir
/-delete
haben keine verlässliche Alternative.Antworten:
Sie können verwenden
-path
, um eine bestimmte Tiefe abzugleichen und dort zu beschneiden. Z.Bwürde maxdepth 1 sein, da
*
Übereinstimmungen mit.
,*/*
Übereinstimmungen./dir1
und*/*/*
Übereinstimmungen,./dir1/dir2
die beschnitten werden. Wenn Sie ein absolutes Startverzeichnis verwenden müssen Sie einen führende hinzufügen/
zu dem-path
zu.quelle
/*
vom Ende des Musters entfernen , den-o
Operator entfernen und das gleiche Ergebnis erzielen?*
Streichhölzer/
, also würde das Dir leidera/b/c/d/e
passen-path */*
.a/b/c/d/e
würde niemals erreicht , da-prune
würde angewandt werdena/b
....-prune
und-o
wurde entfernt. Wenn Sie das beibehalten, besteht-prune
das Problem darin, dass*/*
nichts auf einer Ebene oberhalb der maximalen Tiefe übereinstimmt, za
. B. das einzelne Verzeichnis .@ meuhs Ansatz ist ineffizient, da er
-maxdepth 1
weiterhinfind
den Inhalt von Verzeichnissen auf Ebene 1 liest, um sie später zu ignorieren. Bei einigenfind
Implementierungen (einschließlich GNUfind
) funktioniert dies auch nicht ordnungsgemäß, wenn einige Verzeichnisnamen Folgen von Bytes enthalten, die im Gebietsschema des Benutzers keine gültigen Zeichen bilden (wie bei Dateinamen mit einer anderen Zeichenkodierung).ist der kanonischere Weg, GNUs
-maxdepth 1
(oder FreeBSDs-depth -2
) zu implementieren .Im Allgemeinen ist es jedoch
-depth 1
so, dass Sie es wollen (-mindepth 1 -maxdepth 1
), wie Sie es nicht wollen.
(Tiefe 0), und dann ist es noch einfacher:Denn
-maxdepth 2
das wird:Und hier stoßen Sie auf die Probleme mit ungültigen Charakteren.
Wenn Sie beispielsweise ein Verzeichnis mit dem Namen haben
Stéphane
, dasé
jedoch im Zeichensatz iso8859-1 (auch bekannt als latin1) (0xe9-Byte) codiert ist, wie es in Westeuropa und den USA bis Mitte der 2000er Jahre am häufigsten vorkam, dann ist dieses 0xe9-Byte kein gültiges Zeichen in UTF-8. Also, in UTF-8 - Sprachumgebungen, die*
Platzhalter (mit einigenfind
Implementierungen) nicht übereinstimmenStéphane
als*
0 oder mehr Zeichen und 0xE9 ist kein Charakter.My
find
(wenn die Ausgabe an ein Terminal geht) zeigt dieses ungültige 0xe9-Byte wie?
oben an. Sie können sehen, dasSt<0xe9>phane/Chazelas
war nichtprune
d.Sie können dies umgehen, indem Sie Folgendes tun:
Beachten Sie jedoch, dass dies Auswirkungen auf alle Gebietsschemaeinstellungen
find
und auf alle ausgeführten Anwendungen hat (z. B. über die-exec
Prädikate).Jetzt bekomme ich wirklich eine
-maxdepth 2
aber beachten Sie, wie die in UTF-8 richtig codierten é in der zweiten Stéphane??
als die 0xc3 0xa9-Bytes (betrachtet als zwei einzelne undefinierte Zeichen in der C-Ländereinstellung) der UTF-8-Codierung von é angezeigt werden Nicht druckbare Zeichen im Gebietsschema C.Und wenn ich ein hinzugefügt hätte
-name '????????'
, hätte ich die falsche Stéphane (die in ISO8859-1 codierte) bekommen.Um sie auf beliebige Pfade anzuwenden
.
, gehen Sie wie folgt vor:für
-mindepth 1 -maxdepth 1
oder:für
-maxdepth 2
.Ich würde immer noch Folgendes tun:
Erstens, weil dadurch die Pfade kürzer werden, wodurch es weniger wahrscheinlich ist, dass sie auf einen zu langen Pfad oder eine zu lange Liste von
find
Argumenten stoßen, sondern auch die Tatsache umgangen wird , dass willkürliche Pfadargumente (außer-f
mit FreeBSDfind
) nicht unterstützt werden, da sie ersticken Werte$dir
wie!
oder-print
...Die
-o
Kombination mit Negation ist ein häufiger Trick, um zwei unabhängige Sätze von-condition
/-action
in auszuführenfind
.Wenn Sie in
-action1
Dateikonferenzen-condition1
und unabhängig-action2
in Dateikonferenzen ausführen möchten-condition2
, können Sie Folgendes nicht ausführen :As
-action2
würde nur für Dateien ausgeführt, die beide Bedingungen erfüllen .Noch:
Wie
-action2
würde für Dateien nicht ausgeführt werden, der treffen beide Bedingungen.funktioniert so
\( ! -condition1 -o -action1 \)
, wie es für jede Datei auf true aufgelöst würde . Dies setzt voraus , dass-action1
eine Aktion (wie ) immer true zurückgibt . Für Aktionen wie diese , die möglicherweise false zurückgeben , möchten Sie möglicherweise eine andere hinzufügen, bei der harmlos ist, die jedoch true zurückgibt , wie in GNU oder oder (beachten Sie jedoch das Problem mit ungültigen Zeichen oben).-prune
-exec ... {} +
-exec ... \;
-o -something
-something
-true
find
-links +0
-name '*'
quelle
Ich stieß auf ein Problem, bei dem ich beim Durchsuchen mehrerer Pfade (statt nur
.
) die Tiefe begrenzen musste .Beispielsweise:
Dies führte mich zu einem alternativen Ansatz mit -regex. Das Wesentliche ist:
Das obige wäre also:
Ohne einen Dateinamen:
Schließlich
-maxdepth 2
ändert sich der reguläre Ausdruck zu:'(dir1|dir2)/([^/]*/){0,1}[^/]*$'
quelle
-maxdepth
würde arbeiten mit mehreren Suchpfaden.