Suche im Verzeichnisbaum: find
aus: Wie werde ich UNIX-Guru
und: UNIX-Das umfassende Handbuch
Willemers Informatik-Ecke

Suche einer Datei

Mit dem Kommando find ist es möglich, einen Verzeichnisbaum rekursiv nach Dateien zu durchsuchen und auszugeben oder Aktionen auf die gefundenen Dateien auszuüben. Rekursiv heißt selbstaufrufend und ist eine besondere Programmiertechnik. Da Bäume zu durchlaufen durch rekursive Programme am einfachsten zu realisieren ist, nennt man Bäume rekursive Strukturen und das Durchlaufen der kompletten Äste eines Baumes rekursiv. find ist also ein sehr mächtiger Befehl. Soll nur eine Datei gesucht werden, reicht der vereinfachte Syntax:

find PfadName -name DateiMaske -print

Der Pfadname gibt an, ab welcher Stelle die rekursive Suche beginnt. Die Dateimaske beschreibt die gesuchte Datei. Es können reguläre Ausdrücke verwendet werden. Reguläre Ausdrücke enthalten Platzhalter um die gewünschten Dateien zu beschreiben. Man findet sie auch in anderen Programmen, wie etwa grep.

Kommandos auf gesuchte Dateien

Neben der flexiblen Suche ist die interessanteste Fähigkeit von find die Ausführung eines Kommandos auf jede der gefundenen Dateien. Die zuständige Option heißt -exec. Dahinter wird ein Befehl gesetzt, der mit einem Semikolon abgeschlossen wird. Letzteres muss durch einen Backslash gegen die Interpretation durch die Shell geschützt werden. Die Shell würde das Semikolon als Trennzeichen zwischen zwei Befehlen interpretieren, die nacheinander ausgeführt werden. Vergißt man den Backslash, würde die Shell das Semikolon selbst interpretieren und nicht an find weiterreichen. Der Bezug auf die gefundene Datei wird im Befehl durch ein Paar geschweifter Klammern repräsentiert. Um beispielsweise alle Dateien namens core in den Heimatverzeichnissen zu löschen, würde der Befehl lauten:

find /home -name core -exec rm {} \;

Der erste Parameter gibt an, wo die Suche zu starten hat. -name fordert, dass ein Dateiname, der unter dem Verzeichnis /home gefunden wird, der Dateimaske entspricht. Nur dann wird die Datei von find weiter bearbeitet. Man kann es auch so ausdrücken, dass die Optionen einen Wahrheitswert zurückliefern müssen, der wahr ist, wenn die weiteren Optionen bearbeitet werden sollen. Die Maske zu -name ist einfach core. Nur Dateien mit dem Namen core werden also weiter bearbeitet. Zwischen der Option -exec und dem \; steht der Befehl, der auf die gefundenen Dateien angewandt wird. Der gefundene Dateiname mit seinem Pfad wird dort eingesetzt, wo sich im Befehl das geschweifte Klammerpaar befindet. Fände find eine Datei namens core im Verzeichnis /home/arnold, würde der folgende Befehl generiert und per -exec ausgeführt:

rm /home/arnold/core

Der Befehl find kennt noch einige Optionen, die teils die Suche nach speziellen Dateien ermöglichen und teils die Ausgabe informativer gestalten. Wie oben schon angedeutet, hängt vom dem Wahrheitswert, den die Optionen zurück liefern ab, ob die gefundene Datei weiter bearbeitet wird. Hier sind die wichtigsten Optionen zusammengefasst.

-name DateiMaske
ist wahr, wenn die Dateimaske mit dem gefundenen Dateinamen übereinstimmt. Es können reguläre Ausdrücke verwendet werden.

-print
ist immer wahr. Bewirkt, dass das Ergebnis der Suche angezeigt wird. Bei einigen find-Versionen muss -print nicht explizit angegeben werden, wenn keine weitere Option verwendet wird.

-ls
ist immer wahr. Es bewirkt, dass neben dem Pfadnamen noch ein wenig Statistik angezeigt wird. Dies beinhaltet die folgenden Angaben:
  • i-node Nummer der Datei
  • Größe in Kilobytes (1024 Bytes)
  • Protection mode
  • Anzahl der >>harten<< links
  • Benutzer
  • Gruppe
  • Größe in Bytes
  • Änderungszeitpunkt

-type Zeichen
Der Dateityp wird erfragt. Das Zeichen kann folgende Werte haben:
Zeichen Bedeutung
f Dateien
d Verzeichnisse
l symbolische Links
b c Peripheriedateien
p s Kommunikationsendpunkte (named pipe und socket)

-perm Oktalzahl
Erfragt die Berechtigung, die in oktaler Darstellung wie bei chmod angegeben wird. Beispiel:

find . -perm 0600 -print

Es werden alle Dateien unterhalb des aktuellen Verzeichnisses mit Schreib- und Leserecht für den Benutzer und ansonsten keinen Rechten angezeigt.

Man kann festlegen, dass mindestens die angegebenen Rechte vorhanden sein müssen. Dazu muss der Zahl ein Minuszeichen vorangehen.

-exec Befehl
Ausführen eines Befehls. Die aktuelle Datei wird durch das geschweifte Klammernpaar { } als Argument gekennzeichnet. Der Befehl hört mit einem Semikolon auf. Damit die Shell es nicht selbst interpretiert, muss es mit einem Backslash versehen werden. Beispiel:

find . -exec rm {} \; 

Logische Verknüpfung der Parameter

Man kann die verschiedenen Parameter von find kombinieren. Man könnte beispielsweise nach Dateien suchen, die .rhosts heißen und nicht die Berechtigung 600 haben. Dazu muss man die Aussagen miteinander logisch verknüpfen. Nach den Gesetzen der Logik heißt UND, beide Aussagen müssen zutreffen und ODER, mindestens eine der Aussagen muss zutreffen. Derartige Konstruktionen werden vor allem im Bereich der Shellprogrammierung benötigt. Mit Hilfe der folgenden Operatoren sind logische Ausdrücke kombinierbar:

( )
Eine Gruppe von logischen Ausdrücken und Operatoren in Klammern. Klammern sind besondere Zeichen für UNIX und müssen per Backslash gequotet werden.
!
Die Negation eines logischen Ausdrucks. Das Ausrufezeichen (!) repräsentiert den NICHT-Operator.
-a
Die UND-Verknüpfung von logischen Ausdrücken. Werden mehrere logische Ausdrücke hintereinandergeschrieben, wird dies implizit als UND interpretiert. Man kann auch explizit den -a Operator verwenden.
-o
Die ODER-Vernüpfung von logischen Ausdrücken wird durch den Operator -o erreicht.

Hier als erstes der Befehl der das obige Beispiel aufgreift und alle Dateien namens .rhosts in den Heimatverzeichnissen löscht, die nicht die Berechtigung 600 haben.

find /home -name .rhosts -a ! -perm 0600 -exec rm { } \;

Das folgende Beispiel sucht ab dem aktuellen Verzeichnis alle Dateien, die auf .log oder .aux enden.

find .  -name \*.log -o -name \*.aux

Vor den Sternen muss ein Backslash stehen, damit sie an find durchgereicht und nicht bereits durch die Shell interpretiert werden.

Diese Seite basiert auf Inhalten aus dem Buch Arnold Willemer: Wie werde ich UNIX-Guru.