User Tools

Site Tools


linux:find

This is an old revision of the document!


find

find ist ein umfangreiches Kommandozeilenprogramm für die Dateisuche. Die Suche selbst lässt sich sehr genau mit diversen Filtern für Dateinamen,- typen, -größen und mehr erweitern und kann mit diversen Aktionen kombiniert werden. Eine simplere Suche, bei der nur nach Dateinamen gesucht wird und Treffer im Dateisystem ausgegeben werden, lässt sich mit 'locate' durchführen.

find läuft rekursiv durch die Verzeichnishierarchie, ausgehend von einem Startverzeichnis, versucht Treffer zu den angegebenen Kriterien zu finden und kann anschließend noch Aktionen damit ausführen. Wird nur find aufgerufen, wird als Standardverzeichnis . angenommen und es werden alle Dateien gefunden, inklusive Ordner, symbolische Links, Geräte etc., frei nach dem Leitsatz "Everything is a file". Wird keine Aktion angegeben, wird in der Regel von -print ausgegangen, also die Ergebnisse werden auf der Konsole ausgegeben. Sollen beispielsweise alle mp3-Dateien ausgehend vom aktuellen Verzeichnis ausgegeben werden, lautet der Befehl

find . -name '*.mp3' -print

Oder kurz nur find -name '*.mp3'.

Logische Operationen

Logische Operationen sind auch möglich, so lässt sich beispielsweise nach allen mp3- und ogg-Dateien suchen:

find . \( -name '*.mp3' -o -name '*.jpg' \) -print

Dabei steht -o für or. Ein and lässt sich implizit durch die Eingabe mehrerer flags erreichen:

find . -name '*.mp3' -name '*.jpg' -print

Kombinationen sind ebenfalls möglich:

find . \( -name '*.mp3' -o -name '*.jpg' \) -name 'foo*' -print

Statt nur -name, was je nach Muster nur Dateinamen oder auch Pfade findet, kann mit -path speziell nach Verzeichnisnamen gesucht werden. Dabei ist jedoch zu beachten, dass ein find -path 'bar*' beispielsweise das Verzeichnis ./bar nicht findet, da es mit dem aktuellen Verzeichnis, also ., beginnt. Die Suche find -path './bar*' hingegen findet das Verzeichnis und listet dessen Inhalt.

Eine Negation mittels ! oder -not ist auch möglich, um Begriffe oder Pfade auszuschließen:

find . -name '*.mp3' ! -path '*bar*' -print

So werden alle mp3-Dateien gesucht, wobei Pfade, die “bar” enthalten, ausgeschlossen werden.

Suchkriterien

Es gibt eine Vielzahl an nutzbaren Suchkriterien wie bereits eingangs erwähnt. Die folgende grobe und nicht vollständige Übersicht soll lediglich eine Idee für die Möglichkeiten geben. Eine vollständige Übersicht liefert die Manpage (man find).

Startverzeichnis

  • Suche im aktuellen Verzeichnis: find oder find .
  • Suche im Unterverzeichnis “foo” des aktuellen Verzeichnisses: find foo
  • Suche beginnend im Wurzelverzeichnis, also überall: find /
  • Suche in zwei Verzeichnissen: foo /tmp /var

Dateityp

  • Suche nur nach Dateien: find -type f
  • Suche nur nach Verzeichnissen: find -type d

Name

  • Suche nach vollständigem Namen: find -name foo.bar
  • Suche nach .jpg und .JPG: find -iname '*.jpg'
  • Suche mit Wildcards für einzelne Zeichen: find -name cat.??g' findet unter anderem cat.jpg und cat.png.
  • Suche mit Kombinationen von Wildcards: find -name '*foo*.*x'

Größe

  • Maximale Größe: find -size -100c -ls sucht Dateien, die bis zu 100 Bytes groß sind. Für das “bis zu” steht das -, c steht für “character”, die früher 1 Byte belegten (b ist bereits für “block” vergeben), und -ls liefert eine Auflistung, bei der auch die Größe angezeigt wird.
  • Exakte Größe: find -size 100c -ls
  • Mindestgröße: find -size +10M sucht Dateien, die größer als 10 MB sind. Für “größer” steht das +, statt M kann auch k oder G für kB oder GB verwendet werden.
  • Zwischen Mindest- und Maximalgröße: find -type f -size +64c -size -256c sucht nur nach Dateien, die zwischen 64 und 256 Bytes groß sind.

Alter

Wie bei der Größe gibt es auch hier + für ein Mindestalter, - für ein Höchstalter und ohne Angabe ein exaktes Alter.

  • Änderungszeit in Tagen: find -mtime -365 findet Dateien, die innerhalb der letzter 365 Tage geändert wurden (modification time).
    • ctime: change time, Zeitpunkt der Änderung des Status einer Datei (Name, Rechte), womit sich beispielsweise auch erstellte Dateien finden lassen.
    • atime: access time, Zeitpunkt des Zugriffs auf eine Datei. Bei Bilddateien zählt auch schon die Vorschaufunktion eines grafischen Dateibrowsers. Die Zugriffszeit wird allerdings nicht bei jedem Lesen aktualisiert, erst ab 24h Abweichung.
  • Änderungszeit in Minuten: find -cmin -5
  • Im Vergleich zu einer bestimmten Referenzdatei: find -cnewer /path/rerefence.file

Sonstiges

  • Leere Verzeichnisse und Dateien der Größe 0 finden: find -empty
  • Verzeichnistiefe:
    • Maximale Verzeichnistiefe: find -maxdepth 3 sucht bis zum maximal dritten Unterverzeichnis
    • Minimale Verzeichnistiefe: find -mindepth 2 sucht ab dem zweiten Unterverzeichnis
  • Alle Dateien eines Benutzers finden: find / -user <username>

Kombinationsbeispiele

Finde Dateien ab dem zweiten bis zum maximal vierten Unterverzeichnis, die größer als 25 MB sind und weder .avi, noch .mpg oder .mpeg-Dateien sind:

find -mindepth 2 -maxdepth 4 ! -name "*.avi" -not -name "*.mp*g" -size +25M

Wie bei den logischen Operationen bereits gezeigt, kann eine Klammerung nötig sein, um das gewünschte Resultat zu erzielen. Dabei ist zu beachten, dass eine Klammerung die Reihenfolge der Kombination ändert.

find -name "foo.*" -or -name "bar.*" -name "*.txt"

Ohne Klammern wird zuerst die and-Kombination gebildet, also “bar.*” und “*.txt”, danach erst das or “foo.*”. So würde also ein “foo.jpg” gefunden.

find \( -name "foo.*" -or -name "bar.*" \) -name "*.txt"

Die Klammern müssen maskiert werden! In diesem Fall wird nach “foo.*” oder “bar.*” gesucht, allerdings wird erfordert, dass alle Ergebnisse auf “*.txt” enden müssen.

Aktionen

Anstelle der Ausgabe mittels -print können die gefunden Dateien auch gelöscht werden:

  1. exec rm -f {} \;

Dabei gibt -exec an, wir wollen jetzt ein Kommando ausführen, in diesem Fall rm -f, welches mit ; terminiert wird. Da ein Semikolon allerdings ein spezielles Zeichen in der Shell ist, muss es mit \ maskiert werden. Die geschweiften Klammern sind ein spezielles Argument für find. Jedes Mal, wenn eine Datei gefunden wurde und -exec ausgeführt wird, werden die geschweiften Klammern {} durch den jeweiligen Dateinamen ersetzt.

Ein Beispiel ist es, alle temporären Dateien zu löschen, die länger als 30 Stunden nicht mehr geändert wurden:

find /tmp -type f -mtime +30 -exec rm -f {} \;

Neben -exec gibt es auch -delete, welches die gefundenen Dateien und leeren Verzeichnisse löscht. So kann der zu Beginn dieses Abschnitts angegebene Befehlsteil durch ein delete ersetzt werden.

Weitere Aktionen sind:

  • -ls: Wie weiter oben bereits erwähnt, wird so eine ausführlichere Ausgabe erzeugt.
  • -fprint <filename>: Statt der Ausgabe in der Konsole werden die gefundenen Dateinamen in die Datei <filename> geschrieben.
  • -execdir <command> {} +: Analog zu -exec, allerdings wird das Kommando im Gegensazu zu -exec im Verzeichnis ausgeführt, in dem die jeweilige Datei gefunden wurde. Das + kann (wie auch bei -exec) statt des Semikolons verwendet werden, wenn {} der letzte Parameter ist; so werden alle Funde auf einmal an das Kommando übergeben (s. Beispiel ''md5sum'' weiter unten).
  • -ok <command> {} \;: Wie -exec, jedoch wird vor jeder Aktion um eine Bestätigung gefragt.
  • -okdir: Wie eine Kombination aus -ok und -execdir.

Anwendungsbeispiele

Einige konkretere Anwendungsbeispiele für find. Erklärungen zu komplexeren Beispielen mit xargs und mehr können hier gefunden werden.

Prüfsumme mit ''execdir +''

Erstelle für alle komprimierten tar-Archive eine MD5-Prüfsumme:

find <directory> -type f -name '*.tar.*' -execdir md5sum {} +

In diesem Fall kommt md5sum auch mit einer Liste von Dateien klar, also statt

md5sum a
md5sum b
md5sum c

zu verwenden, was bei dem Aufruf mit -execdir md5sum {} \; passieren würde, kann auch eine Liste von Dateien übergeben werden, wenn die Suche abgeschlossen ist (+):

md5sum a b c

Größte Dateien finden

Finde die größten Dateien in einem Verzeichnis, beginnend bei 20 MB, und sortiere sie nach der Größe:

find <Verzeichnis> -type f -size +20M -exec ls -lh {} \; 2> /dev/null | awk '{ print $NF ": " $5 }' | sort -nrk 2,2

Zuletzt erstellte Dateien finden

Manchmal kommt es vor, dass plötzlich eine Aktion Speicherplatz benötigt und / oder man herausfinden will, was zuletzt auf der Festplatte erstellt wurde. Dazu kann man mit

find / -ctime -2

herausfinden, welche Daten innerhalb der letzter 2 Stunden erstellt wurden (Änderung ihres Status). Oder innerhalb der letzten 15 Minuten:

find / -cmin -15

Das ganze habe ich mir, da es ab und an mal vorkommt, dass z. B. ein Coredump [FIXME Link Coredump Größe beschränken] oder etwas anderes mein root-Verzeichnis zumüllt, eine Funktion in meiner .bashrc angelegt. Wird keine Option verwendet, wird ausgehend von / nach Daten gesucht, die innerhalb der letzten 15 Minuten erstellt wurden (s. Kommando oben).

function last_files(){
    local d=$1
    local t=$2
    [ "$d" == "" ] && d='/'
    [ "$t" == "" ] && t=15
    echo -e "--> Find files created less than $t minutes ago,\n    starting from directory '$d':\n"
    find "$d" -cmin -$t
}
linux/find.1473546820.txt.gz · Last modified: by sascha