Daten sind unsere Leidenschaft!

Nützliche Linux-Befehle, Teil 1

find

find ist einer der am meistbenutzten Shell-Befehle. Mit find kann man in Unix/Linux-Systemen auf Shell-Ebene nach Dateien und Verzeichnissen mit diversen Kriterien suchen. Die Suche kann man auf verschiedene Weise filtern, beispielsweise nach Dateiname, Dateialter oder Dateigröße. Die Ergebnisse kann man formatiert ausgeben und/oder weiterverarbeiten.

Der folgende Artikel bietet eine Auswahl der wichtigsten Suchmöglichkeiten mit find anhand von Beispielen.

Wo kann gesucht werden?

$ find

bzw.

$ find .

findet Dateien im aktuellen Verzeichnis und in allen Unterverzeichnissen.

$ find TEST

findet alle Dateien und Verzeichnisse im Unterverzeichnis „TEST“ des aktuellen Verzeichnisses.

$ find ../

findet alle Dateien und Verzeichnisse im übergeordneten Verzeichnis des aktuellen Verzeichnisses.

$ find /VERZEICHNIS_A

findet alle Dateien und Verzeichnisse im Verzeichnis „VERZEICHNIS_A“ (im absoluten Pfad /VERZEICHNIS_A).

$ find /TEST /VERZEICHNIS_A

findet alle Dateien und Verzeichnisse in den Verzeichnissen /TEST und /VERZEICHNIS_A.

$ find /

findet alle Dateien und Verzeichnisse im Wurzelverzeichnissen und allen Unterverzeichnissen. Mit anderen Worten: dieser Befehl durchsucht das gesamte Dateisystem – das kann dauern! Wenn man das wirklich braucht, dann sollte man in der Testphase weitere Filter angeben, die die Anzahl der gefundenen Dateien einschränken.

Filter setzen

$ find TEST –type f

findet alle Dateien im Unterverzeichnis „TEST“ des aktuellen Verzeichnisses (und in allen Unterverzeichnissen davon), aber keine Verzeichnisse. Das „f“ steht für files.

$ find TEST –type d

findet alle Verzeichnisse im Unterverzeichnis „TEST“ des aktuellen Verzeichnisses (und in allen Unterverzeichnissen davon), aber keine Dateien. Das „d“ steht für directories.

Nach Datei- bzw Verzeichnisnamen bzw. nach Teilen davon suchen

$ find . -name its-people.doc

sucht die Datei its-people.doc im aktuellen Verzeichnis und allen Unterverzeichnissen. Gibt es mehrere Dateien/Verzeichnisse mit diesem Namen, werden alle Treffer aufgelistet.

$ find . -name "*.doc"

sucht DOC-Dateien im aktuellen Verzeichnis und allen Unterverzeichnissen, Groß/Kleinschreibung wird berücksichtigt, d.h. der Befehl findet nur Dateien/Verzeichnisse mit der Endung „.doc“, nicht mit „.DOC“ oder „.Doc“.

$ find . -iname "its*.doc"

sucht alle DOC/doc-Dateien im aktuellen Verzeichnis und allen Unterverzeichnissen die mit „its“ beginnen, ohne Groß/Kleinschreibung zu berücksichtigen.

Nach Größe einer Datei suchen

$ find . -size -1000c -type f -ls

sucht alle Dateien, die bis zu 1000 Bytes belegen. Ein „-“ vor der Zahl bedeutet „bis zu“. Das „ls“ wird hier verwendet, um die gefundenen Ergebnisse im Format „ls -l“ auszugeben.

$ find . -size +1000c -type f -name -ls

sucht alle Dateien, die mehr als 1000 Bytes belegen. Ein „+“ vor der Zahl bedeutet „größer als“.
ls wird hier verwendet um die gefundenen Ergebnisse im Format „ls -l“ auszugeben.

$ find . -size 1000c -type f -name "*.doc" -ls

sucht alle doc-Dateien, die genau 1000 Bytes belegen. (kein + oder – vor der Zahl) Das „ls“ wird hier verwendet, um die gefundenen Ergebnisse im Format „ls -l“ auszugeben.

Das „c“ in den vorausgegangenen Beispielen steht für Character, also Zeichen und diesfalls auch Byte. In Zeiten von Unicode gilt die Äquivalenz von Zeichen und Bytes zwar nicht mehr, aber als „find“ programmiert wurde, konnte man noch davon ausgehen.

Anstelle von „c“ sind auch die Angaben „M“ (Megabyte), „k“ (kilobyte), und „G“ (Gigabyte) zulässig.

$ find . -type f -size +1G -size -2G | wc -l

sucht alle Dateien mit einer Größe zwischen 1G und 2G und gibt die Liste der gefundenen Dateien an „wc -l“ weiter, das seinerseits die Zeilen seiner Eingabe zählt und das Ergebnis ausgibt.

In den Beispielen ist zu sehen, dass man verschiedene Suchkriterien (Filter) miteinander kombinieren kann.

Nach Alter einer Datei suchen

$ find . –mtime -10

sucht alle Dateien, deren Inhalt innerhalb der letzten 10 Tage geändert wurde.

Für die Zeitangaben sind folgende Optionen möglich:

  • mtime („modification time“) – die Zeit, wann die Datei zuletzt verändert wurde
  • ctime („change time“) – die Zeit, wann der Status der Datei (also Name, Rechte etc.) zuletzt geändert wurde
  • atime („access time“) – die Zeit, wann auf die Datei zugegriffen wurde (z.B. mit dem Editor vi).
$ find . -mmin -10

sucht alle Dateien, deren Inhalt innerhalb der letzten 10 Minuten geändert wurde. Mit -cmin würden alle Statusänderungen der letzten 10 Minuten gefunden, mit -amin die Zugriffe (auch ohne Änderung).

$ find . -mmin +10

sucht alle Dateien, deren Inhalt vor mehr als 10 Minuten (+ vor Minute) geändert wurde (-cmin und -amin entsprechend).

Nach 0-Byte-Dateien suchen

$ find . -empty

findet alle leeren Dateien/Verzeichnisse.

Die Suchtiefe auf eine bestimmte Anzahl Verzeichnis-Ebenen beschränken

$ find . -maxdepth 3 -name "*.doc" -type f

findet alle doc-Dateien, durchsucht bis zu 3 Verzeichnisebenen ab dem aktuellen Verzeichnis.

Nach Dateien eines bestimmten Benutzers suchen

$ find / -user Thomas

findet alle Dateien/Verzeichnisse, die dem Benutzer „Thomas“ gehören.

Optionen mit ODER bzw. NICHT

$ find -iname "*Harald*" -or -iname "*Thomas*"

sucht alle Dateien/Verzeichnisse mit „H(h)arald“ oder „T(t)homas“ im Dateinamen.

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

sucht alle Dateien, deren Endung weder *.jpg noch *.png lautet. Einfach aneinandergereihte Filter verhalten sich additiv (UND). Mit „!“ bzw „-not“ (beide Formen sind gleichbedeutend) wird der jeweils folgende Filter negiert.

$ find -iname "*Harald*" -or -iname "*Thomas*" -name *.txt

Zuerst wird die UND-Verknüpfung gebildet (suche nach Dateinamen, die „*thomas*“ beinhalten und mit „*.txt“ enden). Danach wird die ODER-Verknüpfung gebildet (oder Dateinamen die „*harald*“ beinhalten. D.h. eine Datei „harald.doc“ oder „Harald.pdf“ wird gefunden, eine Datei „Thomas.doc“ aber nicht – dafür aber „Thomas.txt“.

Klammerung von Filtern

Klammern beeinflussen die Verknüpfungsreihenfolge:

$ find (-iname "*Harald*" -or -iname "*Thomas*") -name *.txt

Hier wird zuerst die ODER-Verknüpfung gebildet, erst anschließend wird die UND-Verknüpfung hinzugefügt. So werden alle Dateinamen gefunden, die „*thomas*“ oder „*harald*“ beinhalten und zusätzlich mit „*.txt“ enden.

Achtung: Die Klammern müssen jeweils mit einem maskiert werden, sonst verarbeitet die Shell sie schon und reicht sie erst gar nicht an find weiter.

Suchergebnisse direkt weiterverarbeiten

Werden bei find keine weiteren Angaben gemacht, werden die gefundenen Dateien/Verzeichnisse nur aufgelistet. Es gibt jedoch die Möglichkeit, die Ergebnisse der Suche direkt weiterzuverarbeiten.

Gehen wir von folgendem Beispiel aus:

$ find . -name "*datei*"
./datei_004.txt
./datei_002.txt
./test_datei_002.sh
./datei_003.txt
./datei_100_lnk.txt
$

Der Befehl findet im aktuellen Verzeichnis alle Dateien mit „*datei*“ und listet sie auf.

$ find . -name "*datei*" -ls
9437266 4 -rw-r--r-- 1 blog blog 1000 Sep 28 17:53 ./datei_004.txt
9437264 4 -rwxrwxrwx 1 blog blog 500 Sep 28 17:53 ./datei_002.txt
9437271 4 -rwxrwxr-x 1 blog blog 500 Jan 28 08:07 ./test_datei_002.sh
9437265 4 -rw-r--r-- 1 blog blog 1000 Sep 28 17:53 ./datei_003.txt
9437272 0 lrwxrwxrwx 1 blog blog 29 Okt 5 17:46 ./datei_100_lnk.txt -> verzeichnis_100/datei_aaa.txt
$

findet im aktuellen Verzeichnis alle Dateien mit „*datei*“ und listet diese detailiert im ls -l Format auf.

$ find . -name "*datei_003*" -delete -print
./datei_003.txt
$

findet im aktuellen Verzeichnis alle Dateien mit „*datei*““ und löscht diese („-delete“). Das „-print“ listet die gelöschten Dateien zusätzlich auf. Ohne „-print“ erhalten wir keine Rückmeldung auf dem Bildschirm, welche Datei/en gelöscht wurden.

$ find . -name "*datei*" -exec wc -l {} ;
0 ./datei_004.txt
20 ./datei_002.txt
20 ./test_datei_002.sh
40 ./datei_003.txt
4 ./datei_100_lnk.txt
$

findet im aktuellen Verzeichnis alle Dateien mit „*datei*“ und verarbeitet diese weiter mit der Option -exec und dem Befehl „wc -l“ (dieser zählt die Zeilen seiner Eingabe, ermittelt hier also die Anzahl der gefundenen Dateien).

Mit -exec lassen sich unterschiedliche Programme auf der Ergebnisliste ausführen:

$ find . -name "*datei*" -exec rm {} ; - print;
./datei_004.txt
./datei_002.txt
./test_datei_002.sh
./datei_003.txt
./datei_100_lnk.txt
$

findet im aktuellen Verzeichnis alle Dateien mit „*datei*“ und löscht diese („rm“). Durch die Option „-print“ wird wieder jede gelöschte Datei zusätzlich aufgelistet.

Oft benutzt man „-execdir“ statt „-exec“:

$ find . -type d -execdir zip -r gepackt.zip {} ; -print

Diese Option führt den Befehl (hier zip) aus dem Verzeichnis aus, in dem die Datei gefunden wurde. Es wird für jedes Unterverzeichnis ein eigenes gepackt.zip in diesem Verzeichnis angelegt.

Mit -exec würde immer im aktuellen Verzeichnis die Datei gepackt.zip angelegt und somit überschrieben.

Weitere Optionen

  • -ok – fragt im Unterschied zu „-exec“ vor jeder Datei ab, ob man den Befehl ausführen möchte
  • -okdir – fragt im Unterschied zu „-execdir“ vor jeder Datei ab, ob man den Befehl ausführen möchte

Noch mehr Optionen findet man in der manpage zu find.

$ man find

Nützliche Seiten im Internet, auf denen man sich manpages ansehen kann

 

Das könnte Sie auch interessieren

Bleiben Sie informiert:

its-people hilft Ihnen...

Weitere Blogthemen: