Suchbefehl „find“ in der Linux-Konsole (II)

Im ersten Teil dieser Serie habe ich bereits eine ganze Reihe an eher unbekannteren Suchbefehlen behandelt aber den wichtigsten Befehl find ignoriert. Dies war kein böser Wille sondern find ist derartig mächtig und umfangreich, dass man ihn separat behandeln muss. Auch erhebt dies hier nicht einmal im Ansatz den Anspruch auf Vollständigkeit sondern soll einen groben Überblick liefern.

Im Prinzip sucht find ab einem bestimmten Verzeichnis, kann auch das Wurzelverzeichnis / sein, ein bestimmtes Muster und macht eine bestimmte Aktion mit dem Ergebnis – oft einfach nur das Ergebnis auf stdout ausgeben. Nun gilt in der Unix/Linux-Welt das Prinzip „Alles ist eine Datei“ und das wird recht konsequent umgesetzt und dadurch kann man durchaus auch nach Gerätedateien oder Sockets suchen denn sie sind auf dem Dateisystem eine Datei.

find in der einfachsten Form ohne Eingabe von Optionen und Pfaden gibt nur den Inhalt von dem aktuellen Verzeichnis und der Unterverzeichnisse aus und ist eher wertlos. Normalerweise beginnt jede Suche mit find mit der Angabe ab wo im Dateisystem gesucht wird. Bei der Pfadangabe werden übliche Konventionen benutzt.

find mit PfadangabeBedeutung
find /Suche ab dem Wurzelverzeichnis / (kann recht lange dauern und die Belastung der Festplatte kann gewaltig sein)
find ./Suche ab dem aktuellen Verzeichnis
find ../Suche ab dem übergeordneten Verzeichnis
find /varSuche ab dem angegebenen Pfad – hier /var.
find /var /tmpSuche in den beiden angegebenen Pfaden – hier /var und /tmp
find ~/Suche im eigenen Homeverzeichnis.
find ~max/Suche im Homeverzeichnis eines Benutzers – hier max.
find /home/max/Musik*Suche im Homeverzeichnis von einem Benutzer (hier mit kompletter Pfadangabe und der Benutzer max) in Verzeichnissen die mit Musik beginnen.

Hinter der Pfadangabe folgt nun normalerweise das was wir überhaupt suchen. Das können Dateinamen, Pfade, reguläre Dateien, Verzeichnisse, Sockets, Gerätedateien usw. sein. Aber auch Metadaten wie Dateigröße, Alter der Datei, Besitzer der Datei usw. können Suchkriterien sein. In diesem Rahmen können da bei weitem nicht alle Möglichkeiten ausgeschöpft werden und hier empfiehlt sich die Man-Page von find genau zu lesen oder ein gutes Handbuch (wie z.B. Linux in Nutshell) zu benutzen.

Sicher ist die weitaus häufigste Suche mit find die Suche nach Dateinamen. Für diese Suche gibt es zwei Optionen -name und -iname. Die Option name ist case-sensitiv und bei iname wird die Unterscheidung zwischen Groß- und Kleinbuchstaben abgeschaltet. Es ist durchaus möglich bei der Suche mit den beiden Optionen auf Wildcards zurück zu greifen.

find mit verschiedenen Möglichkeiten an Suchen mit der Option -name und -inameBedeutung
find -name script.shExakte Suche nach einem bestimmten Dateinamen
find -name "*.sh"Findet alle Dateien mit der Endung .sh
find -name "script.*"Findet alle Dateien deren Name exakt auf script mit beliebiger Endung passt.
find -name "script.??h"Findet alle Dateien die mit script beginnen und derer Endung mit zwei Zeichen und einem h endet.
find -name "*script.sh"Findet alle Dateien die mit script.sh enden.
find -iname script.shCase-unsensitive Suche und findet alle Dateien deren Name eine Zeichenkette script.sh enthalten egal welche Buchstaben Groß- oder Kleinbuchstaben sind.

Bei vielen gleichartigen, weil systematisch kodierten, Verzeichnissen möchte man evtl. nach bestimmten Verzeichnissen im Verzeichnisbaum suchen und die Dateien dabei ignorieren. Da kommt man mit -name nicht weiter. Für diesen Fall kann man die Suche mit -path einschränken. Jedoch findet hier z.B. die Suche mit -path Dokumente nicht den Ordner „Dokumente“ im gleichen Verzeichnis denn der richtige Pfad würde hier ./Dokumente lauten was wir durch -path ./Dokumente oder -path “*Dokumente“ gerecht werden können. Man kann auch Verzeichnisse bei dieser Suche ausblenden und das erfolgt mit einem nachfolgenden -prune. Wie das funktioniert wird am besten an einem Beispiel erläutert. Gegeben sei folgende Verzeichnisstruktur:

$ tree
.
├── Bilder2019
│   ├── bild1
│   ├── bild2
│   ├── bild3
│   └── bild4
├── Bilder2020
│   ├── bild1
│   ├── bild2
│   ├── bild3
│   └── bild4
└── Bilder2021
├── bild1
├── bild2
├── bild3
└── bild4

3 directories, 12 files

Nun soll das Verzeichnis Bilder2021 von der Suche ausgenommen werden. Dies wird folgendermaßen erreicht:

$ find -path ./Bilder2021 -prune -or -path "./Bilder*" -print
./Bilder2019
./Bilder2019/bild3
./Bilder2019/bild4
./Bilder2019/bild1
./Bilder2019/bild2
./Bilder2020
./Bilder2020/bild3
./Bilder2020/bild4
./Bilder2020/bild1
./Bilder2020/bild2

Das abschließende -print ist hier ausdrücklich nötig, da -prune die Suche beim Auftreten von Bilder2021 zunächst abbricht.

find kann seine Suche auch auf bestimmte Dateitypen einschränken. Dies erfolgt mit der Option -type. Die folgende Tabelle zeigt die verschiedenen Dateitypen:

Option -typeBedeutung
find -type bblockorientierte Spezialdatei
find -type czeichenorientierte Spezialdatei
find -type pbenannte Pipe (FIFO)
find -type dVerzeichnis
find -type freguläre Datei
find -type lsymbolischer Link
find -type sSocket

Man kann mit find auch nach der Größe von Dateien suchen. Dazu sollte man sich aber an die binären Präfixe also Kibibyte, Mebibyte, und Gibibyte  zurück erinnern oder zu Gemüte führen. find kann hier nach Dateien größer als ein angebender Wert, gleich der Größe und kleiner als der angegebene Wert suchen. Dabei können die Präfixe durch das Nachstellen von k, M und G hinter den Zahlenwert erreicht werden. Am besten kann man das durch Beispiele verdeutlichen:

SuchbefehlErklärung
find -size 500cFindet alle Dateien mit einer Größe kleiner 500 Byte (c steht für Character = 1 Byte)
find -size +1GFindet alle Dateien die größer sind als 1 Gibibyte
find -size 4k Findet alle Dateien die zwischen 3073 und 4096 Bytes groß sind denn hier rundet find die Zahlenwerte auf die angegebene Angabe
find -size +256c -size -4096cFindet alle Dateien die größer als 256 Byte aber kleiner als 4096 Byte sind
find -size 2 Findet alle Dateien die exakt zwei Blöcke (512 Byte ist ein Block) belegen – also zwischen 513 und 1024 Byte groß sind

find kann auch anhand der Zeitstempel Suchen durchführen. Dazu möchte ich erst einmal auf den Artikel hier über Zeitstempel unter Linux verweisen. Linux kennt drei verschiedene Zeitstempel nach denen wir auch mit find suchen können.

  • atime
  • mtime
  • ctime

Die Suchoptionen mit denen man die Zeit in vollständigen Tagen (also 0-23 Stunden 59 Minuten und 59 Sekunden) heißen genauso wie die Zeitstempel. Das Gleiche gibt es auch noch für den Minutenbereich:

  • amin
  • mmin
  • cmin

Gültige Suchanfragen nach Zeitstempeln mit Erklärung wären folgende:

find -mtime -30Gefunden werden alle Dateien deren mtime weniger als 30 Tage zurück liegt
find -atime +50Gefunden werden alle Dateien der atime älter als 50 Tage ist
find -cmin -20Gefunden werden alle Dateien deren ctime jünger als 20 Minuten beträgt
find -mmin +60Gefunden werden alle Dateinen deren mtime älter als eine Stunde ist

Nach Benutzer kann man mit der Option -user suchen – find -user max findet alle Dateien die dem Benutzer max gehören. Man kann durch -maxdepth die Suchtiefe einschränken. find / -maxdepth 2 -user max würde alle Dateien finden die dem Benutzer max gehören und ab dem Verzeichnis / ein Unterverzeichnis entfernt ist – das aktuelle Verzeichnis wird mitgezählt. So wie man die maximale Suchtiefe bestimmen kann, so kann man durch -mindepth die Verzeichnistiefe bestimmen ab der gesucht wird. find / -mindepth 2 -maxdepth 4 -user max fängt also im ersten Unterverzeichnis von / an nach Dateien von Benutzer max zu suchen und endet in der dritten Verzeichnistiefe.

Man kann die Optionen des find-Befehls fast beliebig kombinieren und so die Suche sehr exakt einschränken. Zusätzlich dazu kann find mit den Funktionen not und or umgehen:

find „*.jp?g“ -or „*.png“
Dieser Kombination findet Bilder die mit .jpg, .jpeg und .png enden. Eine or-Bedingung wäre z.B.:

find -not -name "*.jpg" -not -name "*.png"

Diese Kombination findet alle Dateien die keine Endung .jpg und .png besitzen. Ein -not kann auch durch ein ! ersetzt werden und das würde nun lauten:

find ! -name "*.jpg" ! -name "*.png"

Kompliziere Suchanweisungen mit not und or können mit Klammern versehen werden.

Als letztes gibt es für den find-Befehl auch noch einen eine Aktion die er ausführt. Im allermeisten Fall gibt er lediglich das Ergebnis auf stdout aus was auch die Option -print impliziert. find kann mit der Option -delete Dateien löschen oder durch -exec können andere Programme die Suchergebnisse bearbeiten. Ein bekanntes Beispiel für exec wäre folgender Fall:

find ./ -exec grep -l beispiel {} \; 2>/dev/null

Diese Kombination sucht ab dem aktuellen Verzeichnis in allen Dateien nach der Zeichenkette „beispiel“ und gibt sie auf STDOUT aus und da dies viele Fehlermeldungen produziert wird STDERR auf das Nulldevice umgelenkt. Da die Fehlermeldung durch die Verzeichnisse produziert werden wäre auch folgende Lösung möglich:

find ./ -type f -exec grep -l beispiel {} \;

denn hier wird mit -type nur nach regulären Dateien gesucht.

Bei find-Suchen mit destruktiven Aktionen kombiniert empfiehlt es sich vorher immer eine Suche zu machen die Ergebnisse zunächst nach stdout ausgibt.

SuchoptionErklärung
-name DateinamenSucht nach einer Datei nach einem Namen
-iname DateinamenSucht nach einem Dateinamen wobei Groß- und Kleinschreibung ignoriert wird
-size [+-] Größe [ckMG]Sucht nach Dateien die größer oder kleiner als Größe ist wobei c für ein Byte und k, M und G für Kibibyte, Mebibyte, und Gibibyte stehen.
Ohne Einheitsangabe wird nach der Anzahl der belegten Blöcke (512 Byte) gesucht.
-type [fdl]Sucht Dateien eines bestimmten Typs: f für reguläre Dateien, d für Verzeichnisse und l für symbolische Links steht.
-atime [+-] ZeitSucht Dateien, auf die seit mehr oder weniger als Zeit Tagen nicht mehr zugegriffen wurde.
-amin [+-] ZeitSucht Dateien, auf die seit mehr oder weniger als Zeit Minuten nicht mehr zugegriffen wurde.
-mtime [+-] ZeitSucht Dateien, die seit mehr oder weniger als Zeit Tagen nicht mehr verändert wurden.
-mmin [+-] ZeitSucht Dateien, die seit mehr oder weniger als Zeit Minuten nicht mehr verändert wurden.
-ctime [+-] ZeitSucht Dateien, deren ctime seit mehr oder weniger als Zeit Tagen nicht mehr verändert wurden.
-cmin [+-] ZeitSucht Dateien, deren ctime seit mehr oder weniger als Zeit Minuten nicht mehr verändert wurden.
-perm 0000Sucht Dateien mit den Zugriffsrechten 0000 (als Oktalzahl)
-user BenutzernameSucht Dateien die dem Benutzer Benutzernamen gehören
-exec Befehl {} \;Führt den Befehl Befehl an den gefundenen Dateien ohne Rückfrage aus
-ok Befehl {} \;Führt den Befehl Befehl an den gefundenen Dateien mit Rückfrage aus

1 Gedanke zu „Suchbefehl „find“ in der Linux-Konsole (II)“

Kommentare sind geschlossen.

kais-universum.de