Suchen Sie Dateien aus verschiedenen Verzeichnissen mit Einschluss und Ausschluss einiger

Suchen Sie Dateien aus verschiedenen Verzeichnissen mit Einschluss und Ausschluss einiger

Ich möchte Dateien aus drei verschiedenen Ordnern finden und dabei bestimmte Dateien ein- und ausschließen.
Ordner 1:

  • Pfad: /var/www/app/var/log/
  • Nur ausschließen: file1.log und file2.log

Ordner 2:

  • Pfad: /var/log/web/log/
  • Nur einschließen: error.log

Ordner 3:

  • Pfad: /var/log/service/log/
  • Nur einschließen: app1.error.log und app2.error.log

Wie würde ich in diesem Fall nach Dateien aus drei verschiedenen Ordnern suchen?

Antwort1

Dies können Sie mit tun find. Lesen Sie mehr über die allgemeine Verwendung von findim Kontext des Ausschließens und Einschließens:Rekursive Suche nach Dateien mit Ausschlüssen und Einschlüssen.

Ihr Problem umfasst drei Pfade und unterschiedliche Anforderungen für jeden. Man kann mehrere Startpunkte in einem einzigen Aufruf angeben findund einen Ausdruck erstellen (z. B. mit -path), sodass für unterschiedliche Pfade unterschiedliche Tests durchgeführt werden. Das ist möglich, aber ziemlich umständlich. Eine einfache Möglichkeit besteht darin, drei separate Suchbefehle nacheinander auszuführen.

find /var/www/app/var/log ! -name file1.log         ! -name file2.log
find /var/log/web/log       -name error.log
find /var/log/service/log   -name app1.error.log -o   -name app2.error.log

Anmerkungen:

  • Mehrere Leerzeichen in den obigen Befehlen dienen lediglich dazu, deren Struktur und Ähnlichkeiten hervorzuheben.

  • Sie sagen: „Ich möchte Dateien finden“. Die obigen Befehle findenDateieneinschließlich Dateien vom Typ „Verzeichnis“; insbesondere findet der erste Befehl seinen eigenen Startpunkt ( …/log). Um nur normale Dateien zu finden, benötigen Sie -type f. Um nur Nicht-Verzeichnisse zu finden, benötigen Sie ! -type d.

  • Wenn file1.logoder app1.error.logvom Typ Verzeichnis ist, ist nicht klar, ob sich „eingeschlossen“ oder „ausgeschlossen“ nur auf das Verzeichnis oder auf das Verzeichnis und alles darunter bezieht. Dies ist wahrscheinlich kein Problem, da es sich bei file1.logund höchstwahrscheinlich um normale Dateien in Ihrem Setup handelt.

    Zur Information: Jeder der obigen Befehle durchläuft den gesamten Verzeichnisbaum unter seinem Startpunkt. Wenn beispielsweise file1.logvom Typ „Verzeichnis“ ist, wird das Testen ! -name file1.lognicht beendet . Um einen Teilbaum auszuschließen, benötigen Sie .findfile1.log/foo-prune

  • findarbeitet rekursiv. Der einfachste Weg, GNU davon abzuhalten, findin Unterverzeichnisse abzusteigen, ist -maxdepth 1. Nicht-GNU-Implementierungen unterstützen dies möglicherweise nicht. Mit rein POSIXfind es ist nicht so einfach.

    Du hast getaggt; Ubuntu stellt GNU findstandardmäßig bereit, sodass Sie es -maxdepth 1frei verwenden können.

  • Richtige Verwendung von-o ist nicht so einfach, wie Sie es sich wünschen.

  • Wenn symbolische Links beteiligt sind, lesen Sie die Informationen -Hzu -Lden Optionen in man 1 find. Möglicherweise möchten Sie eine davon verwenden.


Mit all dem im Hinterkopf kann ich eine Beispielvariante des dritten Befehls erstellen, dieVielleichtpasst besser zu Ihren Bedürfnissen:

find /var/log/service/log/ -maxdepth 1 -type f \( -name app1.error.log -o -name app2.error.log \)

Oder POSIX-mäßig (um die Antwort für ein allgemeineres Publikum nützlicher zu machen):

find /var/log/service/log/. \( -name . -o -prune \) -type f \( -name app1.error.log -o -name app2.error.log \)

Die letzte Komponente des Startpunkts im letzten Befehl endet mit .. Dies ermöglicht uns, eine generische Lösung zu verwenden (ich meine, die Form -name . -o -prunehängt nicht vom wirklich bedeutungsvollen Teil des Startpunktpfads ab). Andererseits findwird /.in jedem Pfadnamen enthalten sein, was Sie möglicherweise nicht möchten.


Das Ausführen von drei finds statt einem hindert Sie nicht daran, die Ergebnisse an ein einzelnes Ziel weiterzuleiten (z. B. xargs):

{ find … ; find … ; find … ; } | xargs …

Hinweis: In Ubuntu können Sie Folgendes tun find … -print0 | xargs -r0 …. Dies istrobusterals find … -print | xargs …, allerdings nicht portierbar.

verwandte Informationen