find

Dieser Artikel wurde für die folgenden Ubuntu-Versionen getestet:

Dieser Artikel ist größtenteils für alle Ubuntu-Versionen gültig.

Zum Verständnis dieses Artikels sind folgende Seiten hilfreich:

  1. Ein Terminal öffnen

Inhaltsverzeichnis
  1. Installation
  2. Übersichten
  3. Beispiele
  4. Weitere Informationen
  5. Links

Wiki/Icons/terminal.png Das Kommandozeilenprogramm find dient der Dateisuche in ganzen Verzeichniszweigen ab definierten Startpunkten. Dabei kann es die Suche auf vielfältige Weise filtern, z.B. nach Dateiname, -alter, -größe und die Suchergebnisse weiterverarbeiten und/oder formatiert ausgeben.

Da unter unixoiden Systemen der Leitsatz "Alles ist eine Datei" gilt, werden auch Verzeichnisse und anderes, was Linux im Dateiverzeichnisbaum einträgt (z.B. Sockets), gefunden. Der Einfachheit halber werden deshalb in diesem Artikel meist nur Dateien genannt. Eine Alternative zu find (mit Vor- und Nachteilen) bietet der Befehl locate.

Installation

Das Programm ist im Paket

von Ubuntu enthalten und ist deshalb auf jedem System vorinstalliert.

Übersichten

Bevor einige praktische Beispiele die vielfältigen Verwendungsmöglichkeiten von find zeigen, zwei kurze Übersichten ...

Einige, wenn auch nicht alle Suchkriterien für find
Kriterium Beschreibung
-name DATEI sucht nach dem Namen DATEI. Werden Platzhalter verwendet, müssen sie maskiert werden, sonst interpretiert sie schon die Shell. Beispiele: \*.txt oder "???.t*xt"
-iname DATEI sucht nach dem Namen DATEI, ohne Beachtung der Groß- und Kleinschreibung.
-type T sucht nach nur einem Typ, z.B. mit f (=file) echte Dateien oder mit d (=directory) Verzeichnisse.
-mtime n sucht nach Dateien, deren Inhalt vor n bis n+1 Tagen geändert (m=modified) wurde.
-mtime +n sucht nach Dateien, deren Inhalt älter als n+1 Tage ist.
-mtime -n sucht nach Dateien, deren Inhalt jünger als n Tage ist.
-ctime n sucht nach Dateien, deren Name oder Status (Modus, Besitzer oder Gruppe) vor n bis n+1 Tagen geändert (c=changed) wurde.
-atime n sucht nach Dateien, auf die zuletzt vor n bis n+1 Tagen zugegriffen (a=accessed) wurde. (Hinweis: Die Aussagekraft der Datei-Zugriffszeit ist stark von den Einhängeoptionen atime, noatime und relatime abhängig.)
-mmin n sucht nach Dateien, deren Inhalt vor n-1 bis n Minuten geändert wurde. (Achtung: andere Zählweise als bei -Xtime)
-mmin +n sucht nach Dateien, deren Inhalt älter als n Minuten ist. (Achtung: andere Zählweise als bei -Xtime)
-mmin -n sucht nach Dateien, deren Inhalt jünger als n Minuten ist. (gleiche Zählweise als bei -Xtime)
-daystart misst für alle darauf folgenden -Xtime- und -Xmin-Kriterien ab 0:00 h des nächsten Tages, also ab Mitternacht.
-newer DATEI sucht nach Dateien, deren Inhalt nach dem von DATEI verändert wurde.
-size n[cwbkMG] sucht Dateien die n Zuordnungseinheiten belegen. Folgende Multiplikatoren können zusätzlich verwendet werden: c für Bytes, w für Zwei-Byte-Wörter, b für 512-Byte-Blöcke (Standard), k für KiB (Kibibyte), M für MiB, G für GiB.
-user BENUTZER sucht nur nach Dateien des Benutzers BENUTZER.
-nouser sucht nach Dateien, deren User-ID keinem Benutzer entspricht.
-nogroup sucht nach Dateien, deren Gruppen-ID keiner Gruppe entspricht.
-maxdepth n sucht ab dem Startpunkt nur n Verzeichnisse tief. Bezeichnet dieser ein Verzeichnis – z.B. implizit das aktuelle Verzeichnis – zählen dessen Einträge schon zu Tiefe 1.
-depth sucht erst rekursiv im Inhalt der Verzeichnisse, bevor das Verzeichnis selbst untersucht wird. (Standard bei -delete Aktion)

Geläufige Aktionen für find
Aktion Beschreibung
-fprint DATEI gibt die gefunden Dateinamen nicht auf die Standardausgabe (Bildschirm) aus, sondern schreibt diese in die Datei DATEI.
-exec KOMMANDO {} \; wendet auf alle Funde den Shellbefehl KOMMANDO an. {} steht dabei als Platzhalter für die gefundenen Dateinamen. Das Zeichen ; terminiert den von find aufzurufenden Shellbefehl. Damit es nicht unbeabsichtigt von der Shell interpretiert wird, muss es mit \ oder zwei umschließenden " maskiert werden.
-execdir KOMMANDO {} + wendet auf die Funde den Shellbefehl KOMMANDO an. Im Gegensatz zu -exec wird das Kommando im Verzeichnis, in dem die Datei liegt, ausgeführt. Das + bewirkt, dass viele Funde (bzw. hier viele eines gleichen Verzeichnisses) auf einmal an KOMMANDO übergeben werden, was die Ausführung stark beschleunigen kann. Das + kann statt dem ; (ebenso wie bei -exec) nur verwendet werden, wenn {} der letzte Parameter von KOMMANDO ist.
-ok KOMMANDO {} \; Wie -exec, allerdings wird vor jeder Aktion eine Bestätigung erfragt. {} steht dabei als Platzhalter für die Funde.
-okdir KOMMANDO {} + Wie eine Kombination von -ok und -execdir, d.h. es wird eine Bestätigung erfragt, und das Kommando wird im Fundordner ausgeführt.
-print erzwingt die Ausgabe der gefunden Dateinamen, auch wenn diese als Parameter für eine andere Aktion zunächst verschluckt wurden. Mit -printf FORMAT kann die Ausgabe auch vielfältig gestaltet werden.
-delete löscht die gefundenen Dateien und leeren Verzeichnisse.

Beispiele

Es gibt eine Unzahl weiterer Beispiele, z.B. die Suche nach Eigentümer, Berechtigungen, Dateisystem u.v.m. Solche und eine komplette Übersicht – auch über die in diesem Artikel nicht beschriebenen Optionen – bieten die Infoseiten und das Manual zu find, sowie die sehr ausführliche Seite findutils auf gnu.org {en}.

Startpunkt(e)

Dort beginnt find mit der Suche – im aktuellen Verzeichnis, wenn keine extra angegeben sind. Startpunkt(e) müssen nach eventuellen Optionen (in diesem Artikel nicht beschrieben) und vor den ebenfalls optionalen Suchkriterien und Aktionen platziert werden. In den meisten Fällen wird es sich dabei um Verzeichnisse handeln, andere Einträge sind aber auch erlaubt. Wenn nicht die ganzen gegebenenfalls dort darunter liegenden Verzeichniszweige durchsucht werden sollen, kann die Durchsuchungstiefe mit zusätzlichen Suchkriterien begrenzt werden.

Name

Pfad(teile)

Will man die Suche auf bestimmte Pfade einschränken, kommt man mit -name nicht weiter. Das Suchkriterium -path ist hier die Lösung, denn es erlaubt die Verwendung des Namenstrenners /.

Typ

Größe

Alter

Auch hier gibt es, ähnlich wie bei der Größe, Mindestalter (+), Höchstalter (-), genaues Alter und Zeitbereiche.

Sonstige Suchkriterien

Kombinationen

Man kann die Suchoptionen aber auch per oder bzw. nicht verknüpfen:

Bei umfangreichen Kombinationen kann eine Klammerung erforderlich sein, um das gewünschte Resultat zu erhalten:

Aktionen

-exec und dessen Varianten

  • Die Anzahl der Zeilen in Textdateien findet man mit wc -l DATEI; kombiniert mit find sieht das so aus:

    find -name "*.py" -exec wc -l {} \; 
    10 ./abc.py
    6 ./x/date-form.py
    102 ./x/download.py

    Das Kommando wc -l (Zeilen zählen) wird auf jede gefundene Datei angewendet. Die geschweiften Klammern werden durch die von find gefundenen Namen ersetzt. Am Ende muss der ganze Befehl mit einem Semikolon abgeschlossen werden. Damit das Semikolon nicht von der Shell interpretiert wird, muss man es mit einem Backslash oder Anführungsstrichen maskieren.

  • Als Parameter für -exec verschluckte Ausgabe von find wieder sichtbar machen

    find tmp -name "a" -exec touch {} \; -print 
    ./tmp/a
    ./tmp/a/a
    ./tmp/a/a/a

    Weil touch nichts ausgibt und man dann deshalb keine Kontrolle darüber hat, was getan wurde, erhält man diese so über die -print-Ausgabe von find.

  • Oft empfiehlt sich -execdir statt -exec

    find startpunkt -type d -execdir tar -cjf archiv.tar.bz2 {} \; 

    -execdir führt das Kommando aus dem Verzeichnis heraus aus, in dem die Datei gefunden wird. So wird also für jedes Verzeichnis ein archiv.tar.bz2 vor Ort angelegt. Mit einem einfachen -exec würde für jedes Verzeichnis ein Archiv im aktuellen Verzeichnis angelegt, d.h. das Archiv immer wieder überschrieben, so dass am Ende nur ein Archiv mit den Ergebnissen der letzten Ausführung von tar verbliebe.

  • Anstatt -exec bzw. -execdir kann man auch -ok bzw. -okdir verwenden

    find -name "*pdf" -okdir xpdf {} \; 

    fragt vor jeder Datei nach, ob man wirklich die Aktion ausführen möchte.

  • Gesammelte Ausführung mit +
    Beendet man ein Kommando mit Plus + statt mit Semikolon ;, so werden mehrere, u.U. alle Funde auf einen Rutsch an das Kommando übergeben. Dies ist nur möglich, wenn das Kommando selbst mit mehreren Parametern zurechtkommt und das + unmittelbar den geschweiften Klammern folgt. Ein Beispiel mit du ergibt zunächst:

    find -name "*pdf" -exec du --total {} ";" 
    16      ./A.pdf
    16      insgesamt
    12      ./B.pdf
    12      insgesamt
    100     ./C.pdf
    100     insgesamt

    Dagegen erhält man ein sinnvolleres Ergebnis mit +:

    find -name "*pdf" -exec du --total {} + 
    16      ./A.pdf
    12      ./B.pdf
    100     ./C.pdf
    128     insgesamt

Weitere Informationen

Alternativen

find ist fast immer das Mittel der Wahl, wenn es darum geht, auch Unterverzeichnisse zu durchsuchen. Wenn man den Dateinamen genau kennt, kann locate eine bessere Wahl sein. locate arbeitet allerdings mit einem Index, der 1x täglich aktualisiert wird, und findet daher ganz frische Dateien nicht.

Für die spezielle Suche nach Programmen wird man whereis benutzen.

Im aktuellen Verzeichnis, ohne Unterverzeichnisse zu berücksichtigen, kommt man mit automatischer Vervollständigung und den Jokerzeichen * und ? oft weiter, wenn man Namensbestandteile kennt. Manche Programme bieten auch von sich aus an, Unterverzeichnisse zu berücksichtigen, siehe ls und Shell/grep.

Typische Fehler

die Ausführung von find läuft (zu) lange

Wenn die Suche mit find läuft, viel zu viele Ergebnisse ausgibt und nicht aufhören will, bricht man find mit Strg + C ab.

Der Pfad muss vor dem Suchkriterium stehen

Wenn man den Stern * nicht maskiert, kommt es oft zu anschließender Meldung:

find /home/ich -name .* 

find: Der Pfad muß vor dem Ausdruck stehen: ..
Aufruf: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [Pfad...] [Ausdruck]

Korrekt ist:

find /home/ich -name ".*" 

Seltsame Größenangaben bei Dateien

Bei der Suche nach Dateigrößen kann man leicht verzweifeln, wenn man nicht dahinter kommt, dass die Vorgabemaßeinheit Blöcke à 512 Bytes sind.

find -size 200c 

sucht nach Größen, die man erwartet.

Seltsames Nichtfinden bei Größen wie k, M, G

Sucht man z.B. nach Dateien, die kleiner als 5 kiB sind, so klingt folgender Befehl zunächst plausibel:

find -size -5k 

Damit werden aber nur Dateien bis maximal 4 kiB gefunden, d.h. es wird keine Datei gefunden, die 4097 Bytes groß ist, denn es wird erst aufgerundet (auf 5k) und dann verglichen. Wenn man Dateien bis 1 Mebibyte suchen wollte führt deshalb -1M nicht zum Ziel – selbst 1 Byte ist größer als die nächstkleinere Ganzzahl in dieser Maßeinheit, also größer als 0M.

Kombination von -or und -and ergibt Unerwartetes

Bei der Oder- und Und-Verknüpfung von Optionen helfen Klammern, Fehler zu vermeiden.

Warnung bei falscher Position von globalen Ausdrucksoptionen

Im Manual zu find wird alles nach den Startpunkten als AUSDRUCK benannt. Dieser kann globale und positionale Optionen (nicht zu verwechseln mit den hier nicht beschriebenen Befehlsoptionen), Tests, Operatoren und Aktionen beinhalten. Stehen globale Optionen, die immer für die ganze Suche gelten, nicht am Anfang des Ausdrucks, so sieht das aus, als habe der Nutzer eine andere Absicht gehabt, und man bekommt deshalb eine Warnung.

Provozieren kann man die Warnung etwa so:

find ./SUCHVERZEICHNIS -maxdepth 4 -name foo -or -maxdepth 2 
find: Warnung: Sie haben die Option -maxdepth nach einem Argument -name angegeben, das keine Option ist, weil Optionen nicht positional sind (-maxdepth beeinflusst sowohl Tests davor als auch jene danach). Bitte geben Sie Optionen vor anderen Argumenten an.

xargs und Schleifen

Oft findet man Konstruktionen mit find ... xargs oder Shellschleifen die find bemühen. Fast immer lässt sich das Problem durch eine der Aktionen (-okdir, -execdir, ...) eleganter lösen.

Die Aktion -delete steht an der falschen Stelle

Der folgende Aufruf löscht den kompletten Inhalt des Ordners /home/ottifant/:

find /home/ottifant/ -delete -name Cache    # falsch!