Schließen Sie ein Unterverzeichnis mit find aus


115

Ich habe eine solche Verzeichnisstruktur

data
|___
   |
   abc
    |____incoming
   def
    |____incoming
    |____processed
   123
    |___incoming
   456
    |___incoming
    |___processed

In allen Ordnern im Datenverzeichnis befindet sich ein eingehender Unterordner. Ich möchte alle Dateien aus allen Ordnern und Unterordnern mit Ausnahme der Verzeichnisse def / incoming und 456 / incoming abrufen. Ich habe es mit folgendem Befehl ausprobiert

 find /home/feeds/data -type d \( -name 'def/incoming' -o -name '456/incoming' -o -name arkona \) -prune -o -name '*.*' -print

aber es funktioniert nicht wie erwartet.

Ravi


3
Dies ist kein guter Rat, aber es wird Sie schnell und schmutzig aus vielen Situationen herausholen: Pfeife, grep -v somethingum auszuschließen, was immer Sie nicht wollen
Miquel

Antworten:


206

Das funktioniert:

find /home/feeds/data -type f -not -path "*def/incoming*" -not -path "*456/incoming*"

Erläuterung:

  • find /home/feeds/data: Starten Sie die Suche rekursiv über den angegebenen Pfad
  • -type f: Nur Dateien finden
  • -not -path "*def/incoming*": nichts mit einschließen def/incomingals Teil seines Pfades auf
  • -not -path "*456/incoming*": Nimm nichts mit 456/incomingals Teil seines Pfades auf

Erhalten eines Fehlers "find: bad option -not find: path-list predicate-list"
Ravi

@ Ravi benutzt du Bash Shell? Ich habe das gerade auf meinem Terminal getestet und es funktioniert für mich. Versuchen Sie stattdessen, die Lösung zu kopieren und einzufügen, wenn Sie Änderungen an Ihrem Skript vorgenommen haben.
Sampson-Chen

Es funktioniert, aber es listet die Verzeichnisse auf, nicht die Dateien in diesen Verzeichnissen.
Ravi

1
-pathEntspricht der gesamten Saite. Wenn Sie dies tun find ., müssen Ihre -pathSaiten./path/to/directory/*
Heath Borders

1
Zu Ihrer -not -pathInformation wird in diesem Beispiel definitiv funktionieren, aber es findwird immer noch in die Verzeichnisstruktur iteriert und es werden CPU-Zyklen verwendet, um alle diese Verzeichnisse / Dateien zu durchlaufen. Um zu verhindern, dass finddiese Verzeichnisse / Dateien durchlaufen werden (möglicherweise befinden sich dort Millionen von Dateien), müssen Sie sie verwenden -prune(die -pruneOption ist jedoch schwierig zu verwenden).
Trevor Boyd Smith

9

Nur zur Dokumentation: Möglicherweise müssen Sie tiefer graben, da es viele Search'n'skip-Konstellationen gibt (wie ich es musste). Es könnte sich herausstellen, dass pruneIhr Freund -not -pathnicht das tut, was Sie erwarten.

Dies ist also ein wertvolles Beispiel für 15 Suchbeispiele, die Verzeichnisse ausschließen:

http://www.theunixschool.com/2012/07/find-command-15-examples-to-exclude.html

Um auf die ursprüngliche Frage zu verlinken, hat das Ausschließen für mich wie folgt funktioniert:

find . -regex-type posix-extended -regex ".*def/incoming.*|.*456/incoming.*" -prune -o -print 

Wenn Sie dann eine Datei suchen und dennoch Pfade ausschließen möchten, fügen Sie einfach hinzu | grep myFile.txt.

Dies kann auch von Ihrer Suchversion abhängen. Aha:

$ find -version
GNU find version 4.2.27
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION SELINUX

5

-nameEntspricht nur dem Dateinamen, nicht dem gesamten Pfad. Sie möchten -pathstattdessen für die Teile verwenden, in denen Sie die Verzeichnisse wie beschneiden def/incoming.


2
find $(INP_PATH} -type f -ls |grep -v "${INP_PATH}/.*/"

7
Einige Erklärungen könnten dies zu einer viel besseren Antwort machen.
Cris Luengo

Vielen Dank für dieses Code-Snippet, das möglicherweise nur begrenzte kurzfristige Hilfe bietet. Eine richtige Erklärung würde ihren langfristigen Wert erheblich verbessern, indem sie zeigt, warum dies eine gute Lösung für das Problem ist, und es für zukünftige Leser mit anderen, ähnlichen Fragen nützlicher machen. Bitte bearbeiten Sie Ihre Antwort, um einige Erklärungen hinzuzufügen, einschließlich der Annahmen, die Sie gemacht haben
Shawn C.

1
Hinweis: Dieser Trick funktioniert nicht, wenn man ihn find ... -print0in Verbindung mit einem späterenxargs -0
phs

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.