Das, was ich verwirrend fand, -prune
ist, dass es eine Aktion (wie -print
) ist, kein Test (wie -name
). Es ändert die "To-Do" -Liste, gibt aber immer true zurück .
Das allgemeine Verwendungsmuster -prune
lautet wie folgt:
find [path] [conditions to prune] -prune -o \
[your usual conditions] [actions to perform]
Sie möchten so ziemlich immer das -o
(logische ODER) unmittelbar danach -prune
, da dieser erste Teil des Tests (bis einschließlich -prune
) für das tatsächlich gewünschte Material (dh das Material, das Sie nicht entfernen möchten ) false zurückgibt.
Hier ist ein Beispiel:
find . -name .snapshot -prune -o -name '*.foo' -print
Dadurch werden die "* .foo" -Dateien gefunden, die sich nicht in den Verzeichnissen ".snapshot" befinden. In diesem Beispiel -name .snapshot
bildet das [conditions to prune]
, und -name '*.foo' -print
ist [your usual conditions]
und [actions to perform]
.
Wichtige Hinweise :
Wenn Sie nur die Ergebnisse drucken möchten, sind Sie möglicherweise daran gewöhnt, die -print
Aktion auszulassen. Sie möchten dies im Allgemeinen nicht tun, wenn Sie verwenden -prune
.
Das Standardverhalten von find ist "und" des gesamten Ausdrucks mit der -print
Aktion, wenn -prune
am Ende keine anderen Aktionen als (ironischerweise) vorhanden sind . Das bedeutet, dass dies geschrieben wird:
find . -name .snapshot -prune -o -name '*.foo' # DON'T DO THIS
ist gleichbedeutend mit dem Schreiben von:
find . \( -name .snapshot -prune -o -name '*.foo' \) -print # DON'T DO THIS
Dies bedeutet, dass auch der Name des Verzeichnisses ausgedruckt wird, das Sie normalerweise entfernen. Dies ist normalerweise nicht das, was Sie möchten. Stattdessen ist es besser, die -print
Aktion explizit anzugeben, wenn Sie dies möchten:
find . -name .snapshot -prune -o -name '*.foo' -print # DO THIS
Wenn Ihre "normale Bedingung" mit Dateien übereinstimmt, die auch Ihrer Bereinigungsbedingung entsprechen, werden diese Dateien nicht in die Ausgabe aufgenommen. Die Möglichkeit, dies zu beheben, besteht darin -type d
, Ihrem Bereinigungszustand ein Prädikat hinzuzufügen .
Nehmen wir zum Beispiel an, wir wollten jedes Verzeichnis .git
entfernen, mit dem begonnen wurde (dies ist zugegebenermaßen etwas erfunden - normalerweise müssen Sie nur das genau genannte Objekt entfernen .git
), aber ansonsten wollten wir alle Dateien sehen, einschließlich Dateien wie .gitignore
. Sie könnten dies versuchen:
find . -name '.git*' -prune -o -type f -print # DON'T DO THIS
Dies würde nicht enthalten .gitignore
in der Ausgabe. Hier ist die feste Version:
find . -name '.git*' -type d -prune -o -type f -print # DO THIS
Zusätzlicher Tipp: Wenn Sie die GNU-Version von verwenden find
, enthält die texinfo-Seite für find
eine ausführlichere Erklärung als die Manpage (wie dies für die meisten GNU-Dienstprogramme gilt).
Laurence Gonsalves
quelle
-prune
funktioniert nicht nur für Verzeichnisse (sondern verhindert bei Verzeichnissen auch die Eingabe von Verzeichnissen, die dieser Bedingung entsprechen, dh hier die Verzeichnisse, die dieser Bedingung entsprechen-name .snapshot
).-prune
übrigens nicht selbst, was dies verursacht. Das Problem ist, dass der oder Operator "kurzschließt" und / oder eine niedrigere Priorität als und hat. Das Endergebnis ist, dass eine aufgerufene Datei.snapshot
mit der ersten übereinstimmt-name
,-prune
dann nichts tut (aber true zurückgibt) und dann oder zurückgibt, da das linke Argument true war. Die Aktion (zB :)-print
ist Teil ihres zweiten Arguments, sodass sie niemals ausgeführt werden kann.-print
am Ende brauche , kann ich jetzt aufhören,\! -path <pattern>
zusätzlich zu-prune
Normalerweise ist die native Art, wie wir Dinge unter Linux tun und wie wir denken, von links nach rechts.
Sie würden also zuerst schreiben, wonach Sie suchen:
Dann drücken Sie wahrscheinlich die Eingabetaste und stellen fest, dass Sie zu viele Dateien aus Verzeichnissen erhalten, die Sie nicht möchten. Lassen Sie uns / media ausschließen, um zu vermeiden, dass Ihre gemounteten Laufwerke durchsucht werden.
Sie sollten jetzt nur Folgendes an den vorherigen Befehl anhängen:
Der letzte Befehl lautet also:
............... | <--- Include ---> | .................... | <- -------- Ausschließen ---------> |
Ich denke, diese Struktur ist viel einfacher und korreliert mit dem richtigen Ansatz
quelle
find
klug genug ist, um die-prune
Klausel zuerst zu verarbeiten. Hmmm, interessant.-prune
von nun an darüber nachdenke ./media
, dass es eintritt , bemerkt, dass es nicht aufgerufen wird,*.php
und dann überprüft, ob es sich gerade im Inneren/media
befindet, es gesehen hat und daher den gesamten Teilbaum übersprungen hat. Es ist immer noch von links nach rechts, es macht nur keinen Unterschied, solange sich beide Prüfungen nicht überschneiden.Beachten Sie, dass -prune nicht verhindert, dass Sie in ein Verzeichnis absteigen, wie einige gesagt haben. Es verhindert das Absteigen in Verzeichnisse, die dem Test entsprechen, auf den es angewendet wird. Vielleicht helfen einige Beispiele (siehe unten für ein Regex-Beispiel). Tut mir leid, dass das so lang ist.
quelle
find . -name test -prune -o -print
: iow,-prune
ist eine Aktion, die auch arbeitet an DateienHinzufügen zu den Ratschlägen in anderen Antworten (ich habe keinen Repräsentanten, um Antworten zu erstellen) ...
Bei der Kombination
-prune
mit anderen Ausdrücken gibt es einen subtilen Unterschied im Verhalten, je nachdem, welche anderen Ausdrücke verwendet werden.Das Beispiel von @Laurence Gonsalves findet die "* .foo" -Dateien, die sich nicht in den Verzeichnissen ".snapshot" befinden: -
Diese etwas andere Kurzschrift listet jedoch möglicherweise versehentlich auch das
.snapshot
Verzeichnis (und alle verschachtelten .snapshot-Verzeichnisse) auf: -Der Grund ist (laut Manpage auf meinem System): -
Das heißt, das zweite Beispiel entspricht der Eingabe des Folgenden, wodurch die Gruppierung von Begriffen geändert wird:
Dies wurde zumindest unter Solaris 5.10 beobachtet. Nachdem ich ca. 10 Jahre lang verschiedene Geschmacksrichtungen von * nix verwendet habe, habe ich erst kürzlich nach einem Grund gesucht, warum dies auftritt.
quelle
-prune
mit und ohne aufmerksam gemacht haben-print
!Prune ist ein nicht wiederkehrender Verzeichniswechsel.
Von der Manpage
Grundsätzlich wird es nicht in Unterverzeichnisse absteigen.
Nehmen Sie dieses Beispiel:
Sie haben die folgenden Verzeichnisse
Wenn Sie laufen
find -name test2
:Es werden beide Verzeichnisse zurückgegeben
Wenn Sie laufen
find -name test2 -prune
:Es wird nur / home / test2 zurückgegeben, da es nicht in / home / test2 absteigt, um / home / test2 / test2 zu finden
quelle
Ich bin kein Experte in diesem Bereich (und diese Seite war zusammen mit http://mywiki.wooledge.org/UsingFind sehr hilfreich )
Gerade bemerkt
-path
ist für einen Pfad, der vollständig mit dem String / Pfad übereinstimmt, der unmittelbar danach kommtfind
(.
in diesen Beispielen), wobei-name
alle Basisnamen übereinstimmen.blockiert das .git-Verzeichnis in Ihrem aktuellen Verzeichnis ( wie Sie es gefunden haben
.
)blockiert alle .git-Unterverzeichnisse rekursiv.
Beachten Sie, dass das
./
extrem wichtig ist !!-path
muss mit einem Pfad übereinstimmen, der verankert ist.
oder was auch immer direkt nach dem Finden kommt, wenn Sie Übereinstimmungen mit ihm erhalten (von der anderen Seite des oder '-o
'), wird dort wahrscheinlich nicht beschnitten! Ich war mir dessen naiv nicht bewusst und es brachte mich dazu, -path zu verwenden, wenn es großartig ist, wenn Sie nicht alle Unterverzeichnisse mit demselben Basisnamen beschneiden möchten: D.quelle
find bla/
dann würden Sie -path .git benötigenbla/
(oder wenn Sie*
stattdessen ein vorne schieben, würde es sich eher wie -name verhalten)Zeigen Sie alles, einschließlich dir selbst, aber nicht den langweiligen Inhalt:
quelle
Wenn Sie alle guten Antworten hier lesen, verstehe ich jetzt, dass die folgenden alle die gleichen Ergebnisse liefern:
Aber der letzte wird viel länger dauern, da er immer noch alles in dir1 sucht. Ich denke, die eigentliche Frage ist, wie
-or
man unerwünschte Ergebnisse herausfindet, ohne sie tatsächlich zu durchsuchen.Ich denke also, dass Pflaumen bedeutet, dass vergangene Spiele nicht anständig sind, sondern als erledigt markiert werden ...
http://www.gnu.org/software/findutils/manual/html_mono/find.html "Dies ist jedoch nicht auf die Wirkung der Aktion '-prune' zurückzuführen (die nur einen weiteren Abstieg verhindert, aber nicht sicher ist) wir ignorieren dieses Element). Stattdessen ist dieser Effekt auf die Verwendung von '-o' zurückzuführen. Da die linke Seite der "oder" -Bedingung für ./src/emacs erfolgreich war, ist es nicht erforderlich, die rechte- zu bewerten. Hand-Seite ('-print') überhaupt für diese bestimmte Datei. "
quelle
find
Erstellt eine Liste von Dateien. Es wendet das von Ihnen angegebene Prädikat auf jedes an und gibt diejenigen zurück, die bestanden haben.Diese Idee, die
-prune
bedeutet, von den Ergebnissen auszuschließen, war für mich wirklich verwirrend. Sie können eine Datei ohne Bereinigung ausschließen:Alles was Sie
-prune
tun müssen, ist das Verhalten der Suche zu ändern. Wenn es sich bei der aktuellen Übereinstimmung um ein Verzeichnis handelt, heißt es "Heyfind
, die Datei, die Sie gerade abgeglichen haben, steigt nicht hinein" . Es wird nur dieser Baum (aber nicht die Datei selbst) aus der Liste der zu durchsuchenden Dateien entfernt.Es sollte benannt werden
-dont-descend
.quelle
Es gibt einige Antworten; Einige von ihnen sind etwas zu theoretisch. Ich werde gehen, warum ich einmal beschneiden musste , also ist vielleicht die Erklärung " Need-First / Beispiel" für jemanden nützlich :)
Problem
Ich hatte einen Ordner mit ungefähr 20 Knotenverzeichnissen, von denen jedes
node_modules
wie erwartet sein Verzeichnis hatte.Sobald Sie in ein Projekt einsteigen, sehen Sie jedes
../node_modules/module
. Aber du weißt wie es ist. Fast jedes Modul hat Abhängigkeiten, also ist das, was Sie betrachten, eher soprojectN/node_modules/moduleX/node_modules/moduleZ...
Ich wollte nicht mit einer Liste ertrinken, die die Abhängigkeit von ...
Wenn ich
-d n
/ kenne-depth n
, hätte es mir nicht geholfen, da sich das Hauptverzeichnis / first node_modules, das ich für jedes Projekt haben wollte, in einer anderen Tiefe befand, wie folgt:Wie kann ich dem ersten eine Liste von Pfaden geben, die am ersten enden,
node_modules
und zum nächsten Projekt wechseln, um dasselbe zu erhalten?Eingeben
-prune
Wenn Sie hinzufügen
-prune
, haben Sie immer noch eine rekursive Standardsuche. Jeder "Pfad" wird analysiert, und jeder Fund wird ausgespuckt undfind
gräbt weiter wie ein guter Kerl. Aber es ist das Ausgraben nach mehr,node_modules
was ich nicht wollte.So ist der Unterschied , dass in jedem dieser verschiedenen Pfaden,
-prune
wirdfind
weiter nach unten zu stoppen zu graben , dass bestimmte Allee , wenn es Ihren Artikel gefunden hat. In meinem Fall dernode_modules
Ordner.quelle