Boolesche Operatoren, genauer die beiden logischen Vertreter UND und ODER, benutzt man bei Suchen ständig. Kombiniert mit Find erlauben sie treffsichere Anfragen.
Der erste Teil von “Finden für Fortgeschrittene” in der letzten Ausgabe [1] hat schon einen ganz guten Eindruck der Mächtigkeit von Find vermittelt. Dabei haben wir uns mit dem erfolgreichen Suchen nach Dateitypen und mit dem Filtern nach Zeit oder Größe vertraut gemacht. Außerdem haben wir uns angesehen, wie man die Treffer gezielt bearbeitet. Diesmal beschäftigen wir uns damit, unerwünschte Suchorte auszuschließen und komplexere Suchen über logische Verknüpfungen zu gestalten.
Wollen Sie Dateien finden, die nicht nur einem bestimmten Namensschema genügen, sondern auch eine vorgegebene Größe und ein maximales Alter aufweisen, benötigen Sie logische Verknüpfungen, etwa das logische Und. Find ermöglicht solche Verknüpfungen mit den Schaltern »-and« und »-or« respektive deren Kurzformen »-a« und »-o«). Implizit wertet Find eine Aneinanderreihung von Ausdrücken stets als UND-Verknüpfung. Suchen Sie im aktuellen Verzeichnis eine echte Datei (also keinen Link oder dergleichen) namens »test.txt«, die mindestens fünf Tage alt und weniger als 3 MByte groß ist, erreichen Sie dies mit einem der völlig gleichwertigen Suchausdrücke aus Listing 1.
Listing 1
UND
$ find . -type f \ -mtime +5 \ -size -3M \ -name test.txt $ find . -type f \ -a -mtime +5 \ -a -size -3M \ -a -name test.txt $ find . -type f \ -and -mtime +5 \ -and -size -3M \ -and -name test.txt
Eine ODER-Verknüpfung macht das Filtern schon viel interessanter. Angenommen, Sie möchten nicht nur Dateien finden, sondern auch Links. Für uns Menschen erscheint es logisch, dass die Konjunktion UND hier nichts anderes bedeutet als eine Vereinigungsmenge: “Finde Objekte vom Typ Datei und finde Objekte vom Typ Link. Liste alle auf.” Logisch korrekt formuliert hieße es aber: “Finde Objekte vom Typ Datei oder Link. Liste sie auf.”
Punkt vor Strich
Nicht formale Sprachen neigen im Gegensatz zu formalen Sprachen dazu, das logische Oder als exklusiv anzusehen: “Möchtest du nach links oder nach rechts abbiegen?” Suchen Sie dagegen nach Dateien, die älter als fünf Tage sind oder (»-o«) eine Größe von mindestens 1 MByte haben, erhalten Sie auch Treffer für Files, für die beides gilt.
Das logische Oder weist zudem eine niedrigere Präzedenz auf als das logische Und. Das verhält sich ähnlich wie bei der Punkt-vor-Strich-Rechenregel: Das UND bindet stärker. Hierzu liefere ich später noch ein paar Beispiele. Sind Sie beispielsweise an Links interessiert, oder aber an Objekten mit einer Größe von mindestens 3 MByte (Abbildung 1), nutzen Sie »-or« (Listing 2, erste Zeile).
Listing 2
ODER
$ find . -type l -or -size +3M $ find . -type f \( -size +3M -or -size -10M \) -iname *.txt
Selbstverständlich können darüber hinaus mehrere ODER-Verknüpfungen vorkommen (Abbildung 2). Spannend wird es, sobald Sie UND- und ODER-Verknüpfungen mischen – etwa, wenn Sie nach Textdateien suchen, die zwischen 3 und 10 MByte groß sind (Abbildung 3). Hier müssen Sie die unterschiedlichen Präzedenzen von UND und ODER beachten und gegebenenfalls Klammern setzen, genau wie beim Rechnen (Listing 2, zweite Zeile).
Die Bash kennt wie die meisten Shells die Klammer als Sprachelement. Daher müssen Sie Klammern, die sich an Find richten, ihre besondere Bedeutung für die Shell nehmen (“escapen”). Dazu stellen Sie ihnen einen Backslash voran.
Pruning
Mit »-prune« lassen Sie Verzeichnisse und Dateien aus. Der Gebrauch des Parameters wirkt auf den ersten Blick etwas verwirrend, klärt sich aber, sobald Sie die allgemeine Formulierung aus der ersten Zeile von Listing 3 verinnerlichen.
Listing 3
Pruning
$ find Ort(e) Prune-Bedingung -prune -o Bedingungen Aktionen $ sudo find \( -path /proc -o -path /sys -o -path /lost\+found -o -path /mnt \) -prune -o -name '.vimrc' -print
Hinter Prune steckt anders als bei »-name« oder »-size« kein Test, sondern wie bei »-print« eine Aktion. Das bedeutet, dass sich durch »-prune« unter Umständen die Liste der auszuwertenden Objekte ändert. Dennoch liefert es an die nachfolgenden Tests stets »true«. Deshalb ist es nahezu immer sinnvoll, nach »-prune« das logische Oder »-or« anzuwenden.
Die Man-Page von Find formuliert die Vorgehensweise etwa so: Die Idee besteht hier darin, dass der Ausdruck vor »-prune« sich auf die zu kürzenden Elemente bezieht. Die Aktion »-prune« selbst gibt jedoch stets »true« zurück. Deswegen stellt das folgende »-o« sicher, dass die Shell die rechte Seite nur für die nicht gekürzten Verzeichnisse auswertet. Der Inhalt der gekürzten Verzeichnisse wird nicht einmal besucht und spielt deswegen keinerlei Rolle.
Zur Illustration einige Beispiele: »find . -name ignoreme -prune -o -print« gibt alle Dateinamen im aktuellen Verzeichnis aus, überspringt aber das Verzeichnis »ignoreme/« und alle darin enthaltenen Dateien. Dagegen liefert »find . -print -name ignoreme -prune« alle Dateien im aktuellen Verzeichnis, inklusive des Verzeichnis »ignoreme/«, nicht aber die Dateien unterhalb von »ignoreme/«.
Manchmal suchen Sie eine ganz bestimmte Datei, deren Namen Sie genau kennen, zum Beispiel die Konfigurationsdatei».vimrc« von Vim. Nun haben Sie unpraktischerweise vergessen, wo genau im Dateisystem sie liegt. Einige Orte kommen dabei jedoch per se nicht infrage, etwa entfernte Dateisysteme (NFS, CIFS, WebDAV). Dasselbe gilt für »/proc« und »/sys«. Hier spielen Sie die volle Stärke von »-prune« aus, indem Sie all diese Verzeichnisse so ausschließen, wie das die zweite Zeile von Listing 3 zeigt.
Fazit
Mit Find haben Sie unter unixoiden Betriebssystemen ein Werkzeug zur Hand, das seinen Namen wirklich verdient. Die hier vorgestellten Möglichkeiten versetzen Sie in die Lage, sehr genau die Dateien zu finden, die Sie benötigen. Die Manpage beschreibt etliche weitere Funktionen, die bestimmte Spezialfälle abdecken. Dementsprechend lohnt es sich auf jeden Fall, hin und wieder einen Blick ins Handbuch zu werfen. (csi)
Infos
- Admin as a Service: Thomas Reuß, “Treffsichere Suche”, LM 04/2023, S. 56, https://www.lm-online.de/49028








