13.4Dateien suchen (find, grep, locate)

Linux bietet eine Menge Möglichkeiten, um nach Dateien zu suchen (siehe Tabelle 13.6). Welches Kommando am besten geeignet ist, hängt davon ab, um welche Art von Datei es sich handelt (Textdatei, Programm etc.) und welche Informationen bekannt sind – z.B. Teile des Dateinamens oder Suchbegriffe für den Inhalt.

Kommando

Funktion

grep

sucht Text in einer Textdatei.

find

sucht Dateien nach Name, Datum, Größe etc.

locate

sucht Dateien nach ihrem Namen.

whereis

sucht Dateien in vordefinierten Verzeichnissen.

which

sucht Programme in PATH-Verzeichnissen.

Tabelle 13.6Kommandos zur Dateisuche

which und whereis

which sucht nach dem angegebenen Kommando. Es liefert den vollständigen Namen des Kommandos, das ausgeführt werden würde, wenn der Kommandoname ohne Pfadinformationen aufgerufen würde.

which durchsucht lediglich die in PATH angegebenen Verzeichnisse und arbeitet daher außerordentlich schnell. PATH enthält eine Liste von Verzeichnissen, in denen sich Programme befinden. Beachten Sie aber, dass PATH für root mehr Verzeichnisse enthält als für gewöhnliche Benutzer. Wenn Sie also Systemkommandos suchen, müssen Sie sich als root einloggen.

user$ which emacs /usr/bin/emacs

whereis durchsucht alle üblichen Pfade für Binärdateien, Konfigurationsdateien, man-Seiten und Quellcode nach dem angegebenen Dateinamen. whereis erfasst damit mehr Verzeichnisse als which und beschränkt sich nicht nur auf Programme. Es versagt allerdings für Dateien, die sich nicht in den für whereis vordefinierten Verzeichnissen befinden (siehe man whereis).

user$ whereis fstab fstab: /etc/fstab /usr/include/fstab.h /usr/share/man/man5/fstab.5.gz

locate

locate muster findet Dateien, bei denen das angegebene Suchmuster im vollständigen Dateinamen vorkommt, also im Pfad plus Dateinamen. Die Suche ist sehr schnell: locate durchsucht nämlich nicht das Dateisystem, sondern greift auf eine Datenbank zurück, die eine Liste aller Dateinamen des Dateisystems enthält. Je nach Distribution zeigt locate nur solche Dateien an, auf die der Benutzer tatsächlich Zugriff hat. Führen Sie locate gegebenenfalls als root aus, wenn Sie nach Systemdateien suchen. locate kann nur benutzt werden, wenn das entsprechende Paket installiert ist, was nicht bei allen Distributionen standardmäßig der Fall ist.

Das folgende Kommando sucht die X-Konfigurationsdatei xorg.conf:

user$ locate xorg.conf /usr/share/X11/xorg.conf.d /usr/share/X11/xorg.conf.d/10-evdev.conf /usr/share/X11/xorg.conf.d/10-quirks.conf /usr/share/X11/xorg.conf.d/11-evdev-quirks.conf ...

Die Suche nach dvips liefert (sofern dieses Paket sowie LaTeX installiert ist) sehr viele Treffer, weil der Suchbegriff in mehreren Verzeichnisnamen vorkommt. Anstatt alle Suchergebnisse anzuzeigen, werden diese mit wc gezählt.

user$ locate dvips | wc -l 421

Die Anzahl der Ergebnisse wird wesentlich kleiner, wenn Sie nur nach Dateien suchen, die mit dvips enden:

user$ locate '*dvips' /usr/bin/dvips /usr/bin/odvips /usr/bin/opdvips /usr/bin/pdvips /usr/local/texmf/dvips /usr/local/texmf/fonts/map/dvips ...

Die Qualität der Suchergebnisse steht und fällt mit der Aktualität der Datenbank für locate. Bei den meisten Distributionen wird die locate-Datenbank einmal täglich durch das Kommando updatedb aktualisiert. updatedb kann natürlich jederzeit auch manuell ausgeführt werden. Das erfordert aber root-Rechte.

Je nach Distribution sind locate und updatedb unterschiedlich implementiert. Bei Debian, Fedora und Ubuntu stellt das standardmäßig installierte Paket mlocate die Kommandos locate und updatedb zur Verfügung. Die Dateidatenbank befindet sich in der Datei /var/lib/mlocate/mlocate.db und wird einmal täglich durch den Cron-Job /etc/cron.daily/mlocate aktualisiert. Die Konfigurationsdatei /etc/updatedb.conf bestimmt, welche Verzeichnisse und Dateisysteme nicht berücksichtigt werden (z.B. CDs, DVDs, diverse Spool-Verzeichnisse).

Bei openSUSE steht locate standardmäßig nicht zur Verfügung. Bevor Sie das Suchkommando nutzen können, müssen Sie das Paket findutils-locate installieren und als root einmalig updatedb ausführen. In Zukunft wird das Kommando einmal täglich durch den Cron-Job /etc/cron.daily/suse.de-updatedb aktualisiert. Die Konfiguration erfolgt durch /etc/sysconfig/locate.

find und grep

find ist ein ebenso leistungsfähiges wie komplexes Kommando zur Suche nach Dateien. Es berücksichtigt verschiedene Suchkriterien: ein Muster für den Dateinamen, die Dateigröße, das Datum der Erstellung oder des letzten Zugriffs etc. Eine vollständige Referenz aller Optionen gibt man find. Die folgenden Beispiele führen aber wohl am besten in den Umgang mit find ein. Beachten Sie, dass find ein vergleichsweise langsames Kommando ist, weil es das Dateisystem Verzeichnis für Verzeichnis durchsucht.

Ohne weitere Parameter liefert find eine Liste aller Dateien im aktuellen Verzeichnis und in allen Unterverzeichnissen:

user$ find ...

Das folgende Kommando sucht alle Dateien im aktuellen Verzeichnis und in allen Unterverzeichnissen, die mit .e beginnen:

user$ find -name '.e*' ./.evolution ./.emacs ./.emacs~ ./.esd_auth ...

find sucht ausgehend vom Verzeichnis /usr/share/texmf alle *.tex-Dateien in einem Verzeichnis, das mit latex endet:

user$ find /usr/share/texmf -path '*latex/*.tex' /usr/share/texmf/ptex/platex/base/plnews03.tex /usr/share/texmf/ptex/platex/base/kinsoku.tex ...

Im nächsten Beispiel sucht find alle Verzeichnisse innerhalb von /etc/. Gewöhnliche Dateien in /etc werden dagegen nicht angezeigt. Die Ergebnisliste wird durch sort alphabetisch geordnet, was standardmäßig nicht der Fall ist.

root# find /etc -type d | sort /etc /etc/acpi /etc/acpi/actions ...

Im Folgenden sucht find alle Dateien in den (Unter-)Verzeichnissen von /home, die Benutzern der Gruppe users gehören und deren Inhalt in den letzten fünf Tagen in irgendeiner Form verändert wurde:

root# find /home -group users -mtime -5 ...

find -mtime +5 findet Dateien, die vor mehr als fünf Tagen verändert wurden, und -mtime 5 liefert solche Dateien, die vor genau fünf Tagen verändert wurden. find rechnet dabei in Vielfachen von 24 Stunden vom aktuellen Zeitpunkt aus. Wenn Sie statt -mtime die Option -ctime verwenden, gilt die inode change time als Änderungszeitpunkt. Dieser Zeitpunkt verändert sich beispielsweise auch dann, wenn nicht der Inhalt, sondern z.B. die Zugriffsrechte verändert werden.

Das folgende Kommando löscht alle Backup-Dateien im aktuellen Verzeichnis und in allen Unterverzeichnissen. Dabei wird die Liste aller infrage kommenden Dateien mit find gebildet und durch Kommandosubstitution ($(kommando)) an rm weitergeleitet.

user$ rm $(find . -name '*~')

Falls es sich um sehr viele Dateien handelt, tritt bei der Ausführung des obigen Kommandos ein Fehler auf: Die Kommandozeile mit allen *~-Dateien wird so lang, dass sie die maximale Kommandozeilenlänge überschreitet. In solchen Fällen müssen Sie entweder die -exec-Option des find-Kommandos oder das Kommando xargs zu Hilfe nehmen.

Das Kommando grep durchsucht eine Textdatei nach einem Suchmuster. Je nach Einstellung der Optionen zeigt das Kommando anschließend die gefundenen Textpassagen an oder gibt einfach nur an, in wie vielen Zeilen das Suchmuster gefunden wurde. Das Suchmuster ist ein sogenannter regulärer Ausdruck.

Das folgende Kommando durchsucht alle *.tex-Dateien des aktuellen Verzeichnisses nach der Zeichenkette »emacs«. Die Liste aller gefundenen Zeilen, denen jeweils der Dateiname vorangestellt ist, wird im Terminal angezeigt.

user$ grep emacs *.tex ...

grep ermittelt hier, wie oft die Funktion arctan in den angegebenen *.c-Dateien verwendet wird:

user$ grep -c arctan\(.*\) *.c

grep -v liefert als Ergebnis alle Zeilen, die das Suchmuster nicht enthalten. Im folgenden Beispiel entfernt grep aus configfile alle Zeilen, die mit dem Zeichen # beginnen – also alle Kommentare. Das nachgestellte cat-Kommando eliminiert außerdem alle leeren Zeilen. Das Endergebnis wird in der Datei nocomments gespeichert. Die Anweisung ist praktisch, wenn wenige Konfigurationszeilen in Hunderten oder Tausenden von Kommentarzeilen untergehen.

user$ grep -v '^#' configfile | cat -s > nocomments

Sie können find und grep auch kombinieren, um besonders wirkungsvolle Suchen durchzuführen. Im folgenden Beispiel durchsucht find alle *.tex-Dateien daraufhin, ob in ihnen die Zeichenkette »emacs« vorkommt. Wenn das der Fall ist, wird der Dateiname auf dem Bildschirm ausgegeben. Beachten Sie, dass die Option -print nicht vor -exec angegeben werden darf. Im Gegensatz zum obigen Beispiel grep emacs *.tex berücksichtigt dieses Beispiel auch *.tex-Dateien in beliebig tief verschachtelten Unterverzeichnissen.

user$ find -name '*.tex' -type f -exec grep -q emacs {} \; -print ...

Das folgende Kommando durchsucht alle Dateien im aktuellen Verzeichnis, die kleiner als 10 kByte sind, nach dem regulären Ausdruck case.*in. Die Liste der gefundenen Dateien wird in der Datei ergebnis gespeichert. Durch die Einschränkung der Dateigröße auf 10 kByte wird versucht, die zumeist erheblich größeren binären Dateien aus der Suche auszuschließen.

user$ find -name '*' -maxdepth 1 -size -10k -exec grep -q \ > case.*in {} \; -print > ergebnis