ubuntuusers.de

Du betrachtest eine alte Revision dieser Wikiseite.

find

Artikel wird überarbeitet

Dieser Artikel wird momentan überarbeitet.

  • Geplante Fertigstellung: 31.03.2017

  • Derzeitig gültiger Artikel: find

  • Bearbeiter: UlfZibis

Solltest du dir nicht sicher sein, ob an dieser Anleitung noch gearbeitet wird, kontrolliere das Datum der letzten Änderung und entscheide, wie du weiter vorgehst.


Achtung: Insbesondere heißt das, dass dieser Artikel noch nicht fertig ist und dass wichtige Teile fehlen oder sogar falsch sein können. Bitte diesen Artikel nicht als Anleitung für Problemlösungen benutzen!

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:

Wiki/Icons/terminal.png find ist ein Kommandozeilenprogramm für die Dateisuche. Dabei kann man auf vielfältige Weise die Suche 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 andere äquivalente Objekte gefunden. Es wird der Verzeichnisbaum ab den ggf. explizit bezeichneten Startpunkten durchsucht. Eine Alternative zu find (mit Vor- und Nachteilen) bietet der Befehl locate.

Installation

Das Programm ist im Paket

  • findutils

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.

Suchkriterien

Im Folgenden sind einige, wenn auch nicht alle Suchkriterien aufgeführt.

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. Z. B: \*.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 und 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. (Achtung: 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 wie bei -xtime)
-mmin +n sucht nach Dateien, deren Inhalt älter als n Minuten ist. (Achtung: andere Zählweise wie bei -xtime)
-mmin -n sucht nach Dateien, deren Inhalt jünger als n Minuten ist. (gleiche Zählweise wie bei -xtime)
-newer DATEI sucht nach Dateien, deren Inhalt nach dem von DATEI verändert wurde.
-size n[cwbkMG] sucht Dateien die n Zuordnungseinheiten belegen. Folgende Marker 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. . – zählt dessen Inhalt schon zu Tiefe 1.
-depth sucht erst rekursiv im Inhalt der Verzeichnisse, bevor das Verzeichnis selbst untersucht wird. (Standard bei -delete Aktion)

Aktionen

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 \ maskiert werden.
-execdir KOMMANDO {} + wendet auf alle Funde den Shellbefehl KOMMANDO an. Im Ggs. zu -exec wird das Kommando im Verzeichnis, in dem die Datei liegt, ausgeführt. Das + kann (ebenso wie im Kommando -exec) statt ; verwendet werden, wenn {} der letzte Parameter ist; es werden dann mehrere Funde auf einmal an KOMMANDO übergeben.
-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.
-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 erwähnten Optionen – bieten die Manpage und die Infoseiten zu find sowie die sehr ausführliche Seite findutils auf gnu.org 🇬🇧.

Startpunkt(e)

Dort beginnt find mit der Suche. Wenn nicht extra angegeben, wird . impliziert. Startpunkt(e) müssen nach evtln. Optionen 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 ggf. dort darunter liegenden Verzeichnisbäume durchsucht werden sollen, können diese beidseitig mit zusätzlichen Suchkriterien begrenzt werden.

  • find 

    sucht ab dem aktuellen Verzeichnis, findet also auch . .

  • find foo 

    sucht ab foo des aktuellen Verzeichnisses.

  • find ../ 

    sucht ab dem übergeordneten Verzeichnis.

  • find /tmp 

    sucht ab einem ganz anderen Ort (ab dem absoluten Pfad /tmp).

  • find /tmp /boot 

    sucht ab zwei Orten (sowohl ab /tmp als auch ab /boot).

  • find Film* 

    sucht im aktuellen Verzeichnis Einträge die mit "Film" beginnen, also u.a. Dateien und alles in mit "Film" beginnenden Pfaden (* wird hier schon von der Shell erweitert).

  • find / 

    sucht überall (ab dem Wurzelverzeichnis - das kann dauern!).

Name

  • find -name hausarbeit.odt 

    sucht nach den vollständigen Namen hausarbeit.odt.

  • find -name "*.pdf" 

    sucht nach PDF-Dateien. -name (berücksichtigt die Groß-/Kleinschreibung, findet hier also keine Datei(en) mit Endung *.PDF).

  • find -iname a\*.pdf 

    sucht nach .pdf- und .PDF-Dateien, die mit a oder A beginnen (ignoriert die Groß-/Kleinschreibung).

  • find -name "katze.*" 

    findet katze.jpg, katze.png, katze.txt usw.

  • find -name "katze.??g" 

    findet katze.jpg, katze.png usw. (jedes Fragezeichen steht für ein einzelnes Zeichen).

  • find -name "*foo*.*x*" 

    findet foo.x, afoo.x, foob.txt usw.

Pfad(teile)

Sucht man mittels Pfadteilen, kommt man mit -name nicht weiter. Das Suchkriterium -path ist hier die Lösung, denn es erlaubt die Verwendung des Namenstrenners /.

  • find -path "*2013/J*" 

    findet ~/fotos/2013/Juni und ~/musik/2013/Juli, aber nicht ~/dokumente/2013-Juni.

Typ

  • find -type f 

    findet nur reguläre Dateien, Verzeichnisse etc. werden ausgelassen.

  • find -type d 

    findet nur Verzeichnisse, aber keine sonstigen "Dateien".

Größe

  • Maximale Größe

    find -size -100c -ls 

    sucht nach Dateien, die kleiner als 100 Bytes sind, wofür das - vor der Zahl 100 steht. Das c dahinter bedeutet character, welche früher 1 Byte belegten (b ist schon für die Maßeinheit Block (= 512 Bytes) vergeben). Mittels dem zusätzlichen -ls läßt sich die Größe der gefundenen Dateien überprüfen. Deswegen wird es hier, vor den anderen Aktionen, erwähnt.

  • Exakte Größe

    find -size 100c 

    sucht nach Dateien, die genau 100 Bytes groß sind (kein Vorzeichen).

  • Mindestgröße

    find -size +100M 

    sucht nach Dateien, die größer als 100 Mebibytes sind (Vorzeichen +). Statt M kann man auch k für Kibibytes oder G für Gibibytes angeben.

  • Mindestgröße einschließlich

    find ! -size -100M 

    sucht nach Dateien, die mindestens 100 Mebibytes groß sind (! steht für nicht).

  • Zwischen Mindest- und Maximalgröße

    find -type f -size +64c -size -4096c | wc -l 

    sucht nach Dateien, die zwischen 65 und 4095 Bytes groß sind, und wird per Pipe an wc übergeben, um die Anzahl der gefundenen Dateien zu bestimmen.

  • Blockbelegung

    find -size 2 

    sucht nach Dateien, die 2 Blöcke belegen, also von 513 bis 1024 Bytes Größe. Ohne Maßeinheit wird die Zahl als Anzahl belegter Blöcke à 512 Bytes interpretiert; die Angabe von b ist also optional. Wenn es Probleme mit der Größe gibt, dann wahrscheinlich, weil man c, k, M oder G vergessen hast.

Alter

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

  • Änderungszeit in Tagen

    find -mtime -100 

    sucht nach Dateien, deren Inhalt innerhalb der letzten 100 Tage geändert wurde (mtime = modification time). Weitere Optionen sind

  • Änderungszeit in Tagen

    find -mtime +100 

    sucht nach Dateien, deren Inhalt vor mehr als 101 Tage geändert wurde. Dateien, die zwischen 100 und 101 Tage alt sind, werden also von keinem der beiden vorangehenden Suchkriteriumsbeispielen gefunden! Weitere Optionen sind

    • ctime (change time): Zeitpunkt, an dem der Name oder Status (Besitzer, Gruppe, Rechte) der Datei geändert wurde, oder

    • atime (access time): Zeitpunkt, an dem auf die Datei zuletzt zugegriffen wurde. Eine Dateiauflistung selbst ist damit nicht gemeint. Bei Bilddateien z.B. zählt aber die Vorschaufunktion eines grafischen Dateimanagers oder das Auslesen der Bildeigenschaften bereits als Zugriff. Die Zugriffszeit wird erst bei mehr als 24 h Abweichung oder wenn sie älter als die letzte Änderung der Datei ist, also nicht bei jedem Lesen, aktualisiert (wenn das Dateisystem nicht mit vom Standard abweichenden zusätzlichen Optionen eingehangen ist).

  • Zugriffszeit in Minuten

    find -amin -5 

    sucht nach Dateien, auf die in den letzten 5 Minuten zugegriffen wurde. Analog: -cmin, -mmin. Bei +5 werden hier alle Dateien gefunden, auf die vor mehr als 5 Minuten zugegriffen wurde, es entsteht also keine Lücke wie bei -xtime.

  • Im Vergleich zu einer bestimmten Datei

    find -cnewer /tmp/referenz 

    sucht nach Dateien, deren Name oder Status nach der Änderungszeit der Referenzdatei geändert wurden. Mit touch --date='2004-02-29 15:00' /tmp/referenz erstellt man sich eine Referenzdatei, wenn man keine hat.

Sonstige Suchkriterien

  • Alle Dateien des Benutzers Klaus:

    find / -user klaus 

  • Leere Verzeichnisse und Dateien der Größe 0

    find -empty 

  • Verzeichnistiefe

    find -maxdepth 3 

    steigt bei der Suche nur 3 Verzeichnisebenen herab.

    find -mindepth 0 

    schließt die Startpunkte selbst – z.B. . – von der Suche aus.

Kombinationen

  • Standard: Und-Kombination; die Funde müssen alle Kriterien erfüllen

    find -mindepth 3 -maxdepth 5  

    sucht in Verzeichnistiefe 3 bis 5.

  • Weiteres Beispiel der Und-Kombination:

    find -mindepth 3 -type f -name "*.avi" -size +5M 

    beginnt die Suche in Verzeichnistiefe 3, und findet nur reguläre Dateien, die die Endung .avi haben und mindestens 5 MiB groß sind.

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

  • Negation

    find ! -name "*.avi" -not -name "*.mp*g" 

    sucht Dateien die weder die Dateiendung avi noch mpg oder mpeg haben. Ausrufezeichen und -not sind gleichbedeutend.

  • Oder-Kombination

    find -name "susi.*" -or -name "susanne.*" 

    sucht Dateien die mit "susi." ober "susanne." beginnen.

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

  • ohne Klammern

    find -name "susi.*" -or -name "susanne.*" -name "*.txt" 

    Ohne Klammern wird erst die UND-Verbindung gebildet, also "susanne.*" und "*.txt", danach erst ODER mit "susi.*". Auch susi.png würde also gefunden.

  • mit Klammern

    find \( -name "susi.*" -or -name "susanne.*" \) -name "*.txt" 

    Hier wird jetzt für alle Dateien gefordert, dass diese auf ".txt" enden. Klammern müssen maskiert werden.

Aktionen

  • Ohne weitere Angaben gibt find die Namen der gefundenen Dateien aus:

    find /boot/grub/ -name "he*" 
    /boot/grub/hexdump.mod
    /boot/grub/hello.mod
    /boot/grub/help.mod

  • Wie bereits weiter oben erwähnt kann man mit -ls eine detailliertere Ausgabe erzeugen:

    find /boot/grub/ -name "he*" -ls 
    168624    4 -rw-r--r--   1 root     root         3196 Jan 13 17:08 /boot/grub/hexdump.mod
    168603    4 -rw-r--r--   1 root     root         1308 Jan 13 17:08 /boot/grub/hello.mod
    168623    4 -rw-r--r--   1 root     root         2200 Jan 13 17:08 /boot/grub/help.mod

Mit -exec und dessen Varianten lassen sich beliebige Programme auf den Fundstellen ausführen.

  • 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 ./x/abc.py
    6 ./x/date-form.py
    102 ./x/download.py

    Das Kommando wc -l (Anzahl der 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.

  • die Kombination mit -print

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

    touch setzt das Datum der Dateien auf den Ausführungszeitpunkt. Da touch aber nicht den Dateinamen ausgibt sieht man nicht, welche Dateien nun betroffen waren. Daher schickt man ein -print hinterher.

  • Anstatt -exec kann man auch -ok verwenden. Hierbei wird jedes mal gefragt, ob man die Aktion ausführen möchte.

  • Meist empfiehlt sich -execdir statt -exec

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

    -execdir führt das Kommando aus dem Verzeichnis heraus aus, in dem die Datei gefunden wird. So wird also für jedes Unterverzeichnis ein archiv.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 des letzten Verzeichnisses existiert.

  • -okdir

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

    -okdir fragt im Gegensatz zu -execdir vor jeder Datei nach, ob man wirklich die Aktion ausführen möchte.

  • Gesammelte Ausführung mit +

    find -name "*pdf" -execdir md5sum {} + 

    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 dann sinnvoll, wenn das Kommando selbst mit mehreren Parametern zurechtkommt. Beispiele:

    find test -type f -execdir md5sum {} ";" 

    ergibt:

    md5sum a
    md5sum b
    md5sum c

    Dagegen ergibt:

    find test -type f -execdir md5sum {} + 
    md5sum a b c 

    Das + kann nur verwendet werden, wenn die geschweiften Klammern unmittelbar davor stehen.

  • Eine etwas heikle Angelegenheit ist das Löschen mit der Option -delete.

    Achtung!

    Da find auch Unterverzeichnisse durchsucht, sollte mit dieser Option vorsichtig umgegangen werden. Mit find gelöschte Dateien landen nicht im Papierkorb und können nicht wieder hergestellt werden. Siehe auch Die Aktion -delete steht an der falschen Stelle

    Vor der Verwendung sollte ein Test ohne -delete voraus gehen, um sicher zu gehen, nicht zu viele Dateien zu löschen. Die -delete-Option impliziert -depth, d.h. man muss zum Testen auch -depth setzen, um keine Überraschung zu erleben:

    find test/ -depth -name "c*" 

    Es ist auch sorgfältig darauf zu achten, an welcher Position -delete steht.

    find test/ -name "c*" -delete 

    Löscht im Verzeichnis test und dessen Unterverzeichnissen alle Dateien, die mit 'c' beginnen. Der Befehl löscht auch Verzeichnisse selbst, die mit 'c' beginnen, sofern sie leer sind, wie allgemein üblich bei Linux. Das ist der Grund, weshalb -delete ein -depth impliziert: Wenn erst in den Verzeichnissen gelöscht wird kann ein dadurch leeres auch selbst gelöscht werden, umgekehrt nicht.

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

find ohne Ende

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

Der Pfad muss vor dem Suchkriterium stehen

Wenn man den Stern * nicht maskiert kommt es oft zu folgender Meldung:

find /tmp -name *sh 
find: Der Pfad muß vor dem Suchkriterium stehen: adhoc.sh
Aufruf: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [Pfad...] [Suchkriterium]

Mit

find /tmp -name "*sh" 

ist das leicht geheilt.

Seltsame Größen

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

find -size 200c 

sucht nach Größen, die man erwartet.

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

Sucht man nach Dateien, die kleiner sind als 1000k, so werden Dateien bis maximal 999k gefunden:

find -size -1000k 

Das klingt zunächst plausibel, aber es wird keine Datei gefunden, die 999001 Bytes groß ist, denn es wird erst aufgerundet (auf 1000k) und dann verglichen (nicht kleiner als 1000k). Krasser noch, wenn man Dateien bis 1M suchen wollte - selbst 1 Byte ist größer als die nächstkleinere Ganzzahl in dieser Maßeinheit, also größer als 0M, und wird daher nicht gefunden. Das ist nicht sehr intuitiv, also Obacht.

Kombination mit -or (und evtl. -and) ergibt unerwartetes

Bei Oder- und Und-Verknüpfungen von mehreren Optionen helfen Klammern Fehler zu vermeiden.

Positionssensitiv

Bei mehreren Optionen und Ausdrücken (options und expressions) unterscheiden sich erstere von zweiteren dadurch, dass Optionen nicht mit -or gruppiert werden können - die Optionen werden immer für die ganze Suche verwendet. Stehen die Optionen hinter Ausdrücken, so sieht das aus, als habe der Nutzer eine andere Absicht gehabt, und man bekommt eine Warnung:

Folgende Meldung erhält man, wenn man Optionen nach Argumenten benutzt.

find tmp -name "a" -maxdepth 3 -mindepth 3 
find: Warnung: Sie haben die Option -maxdepth nach dem Argument -name angegeben, aber Optionen sind nicht positionssensitiv (-maxdepth beeinträchtigt sowohl Tests, die vor ihr als auch nach ihr definiert sind). Diese Optionen ist vor den anderen Argumenten anzugeben.

Provozieren kann man die Warnung etwa so:

find ./SUCHVERZEICHNIS -maxdepth 4 -name foo -or -maxdepth 2 

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

So löscht z.B. der folgende Aufruf den kompletten Inhalt des Ordners /home/otto/:

find /home/otto/ -delete -name Cache 

Diese Revision wurde am 22. März 2017 20:10 von UlfZibis erstellt.
Die folgenden Schlagworte wurden dem Artikel zugewiesen: Shell