# find - Dateien und Verzeichnisse suchen Der Befehl `find` durchsucht Verzeichnisse rekursiv nach Dateien oder Ordnern anhand verschiedener Kriterien. ## Grundsyntax ```bash find [Pfad] [Suchkriterien] [Aktionen] ``` ## Suchkriterien ### Nach Namen suchen ```bash find . -name "datei.txt" # exakte Übereinstimmung find . -iname "datei.txt" # case-insensitive find . -name "*.log" # mit Wildcards ``` ### Nach Dateityp suchen ```bash find . -type f # nur Dateien find . -type d # nur Verzeichnisse find . -type l # symbolische Links ``` ### Nach Dateigröße suchen ```bash find . -size +10M # größer als 10 MB find . -size -100k # kleiner als 100 KB find . -size 0 # leere Dateien ``` ### Nach Berechtigungen suchen ```bash find . -perm 644 # Dateien mit Rechten 644 find . -user alice # Dateien von User "alice" find . -group admins # Dateien von Gruppe "admins" ``` ### Suchtiefe begrenzen ```bash find . -maxdepth 1 -type f ``` Nur im aktuellen Ordner, nicht in Unterordnern. ## Suche nach Datum und Zeit ### Zeitstempel-Typen - **mtime** (modification time) = Inhalt geändert - **atime** (access time) = Datei gelesen - **ctime** (change time) = Metadaten geändert (chmod, chown) ### Relative Zeitangaben (Tage) ```bash find . -mtime -7 # in den letzten 7 Tagen geändert find . -mtime +30 # älter als 30 Tage find . -atime -1 # in den letzten 24 Stunden geöffnet find . -ctime -1 # Metadaten in letzten 24h geändert ``` Dateien zwischen X und Y Tagen: ```bash find . -mtime +7 -mtime -30 ``` ### Absolute Zeitangaben (Datum, GNU find) ```bash find . -newermt "2025-04-01" # mtime nach Datum find . -newerat "2025-04-01" # atime nach Datum find . -newerct "2025-04-01" # ctime nach Datum find . -newermt "2023-09-01" ! -newermt "2023-09-10" # zwischen zwei Daten ``` **Hinweis:** `-newermt/at/ct` sind GNU-Erweiterungen (nicht auf BSD/macOS). ### Mit Referenzdatei ```bash touch -d "2025-04-01" /tmp/refdate find . -newer /tmp/refdate ``` ### Übersicht Zeitoptionen | Option | Bedeutung | |--------|-----------| | `-mtime -7` | in den letzten 7 Tagen geändert | | `-mtime +30` | älter als 30 Tage | | `-atime -2` | in den letzten 2 Tagen geöffnet | | `-ctime -1` | Metadaten in letzten 24h geändert | | `-newermt "2023-09-01"` | mtime nach Datum (GNU) | | `-newerat "2023-09-01"` | atime nach Datum (GNU) | | `-newerct "2023-09-01"` | ctime nach Datum (GNU) | | `-newer datei.txt` | neuer als Referenzdatei | ## Bedingungen kombinieren ### UND-Verknüpfung (Standard) ```bash find . -type f -size +1M -mtime -7 ``` Dateien größer als 1 MB UND in den letzten 7 Tagen geändert. ### ODER-Verknüpfung ```bash find . -type f \( -name "*.jpg" -o -name "*.png" \) ``` Alle `.jpg` ODER `.png` Dateien. ### Negation ```bash find . -type f ! -iname "*.mp3" ``` Alle Dateien, die NICHT auf `.mp3` enden. Mehrere Endungen ausschließen: ```bash find . -type f ! \( -iname "*.mp3" -o -iname "*.flac" \) ``` ## Aktionen auf gefundene Dateien ### Anzeigen ```bash find . -name "*.log" -print # Standard find . -name "*.log" -ls # mit Details ``` ### Dateien löschen **Grundprinzip:** Immer erst testen, dann löschen! ```bash # 1. Testen find . -name "*.tmp" -print # 2. Anzahl prüfen find . -name "*.tmp" | wc -l # 3. Dry-run find . -name "*.tmp" -exec echo rm {} + # 4. Löschen find . -name "*.tmp" -delete ``` Alternative mit `-exec`: ```bash find . -name "*.tmp" -exec rm {} + # effizient (mehrere auf einmal) find . -name "*.tmp" -exec rm {} \; # einzeln find . -name "*.tmp" -exec rm -i {} \; # mit Rückfrage ``` Mit xargs (sicher bei Leerzeichen): ```bash find . -name "*.tmp" -print0 | xargs -0 rm ``` ### Mit -exec Befehle ausführen ```bash find . -name "*.log" -exec rm {} + # Löschen find . -type f -name "*.sh" -exec chmod +x {} + # Ausführbar machen find /etc -type f -mtime -1 -exec cp {} /backup/ \; # Kopieren find . -type f -name "*.log" -mtime +7 -exec gzip {} + # Komprimieren ``` - `{}` = Platzhalter für gefundene Datei - `\;` = Ende des Befehls (einzeln, langsamer) - `+` = mehrere Dateien gleichzeitig (effizienter) ### Komplexe Shell-Befehle ```bash find . -type f -name "*.jpg" -exec sh -c 'for f; do convert "$f" -resize 800x "${f%.jpg}_small.jpg" done' _ {} + ``` ## Pfad- und Namensfilter ### Mit -path (Glob-Muster) ```bash find ~/Musik -type f -path "*/zzz Verschiedene/AlbumArt_*" ``` `-path` verwendet Shell-Wildcards (Globs), nicht reguläre Ausdrücke. ### Mit -regex (Reguläre Ausdrücke) ```bash find ~/Musik -type f -regextype posix-extended \ -regex '.*/zzz Verschiedene/AlbumArt_.*' ``` `-regex` matcht den gesamten Pfad, daher oft `.*` am Anfang nötig. ## Praktische Anwendungsfälle ### Alte Dateien löschen ```bash find /tmp -type f -mtime +7 -delete ``` ### Leere Dateien/Verzeichnisse finden ```bash find . -type f -empty # leere Dateien find . -type d -empty # leere Ordner ``` ### Dateien mit falschen Rechten ```bash find / -type f -perm -o+w # weltweit schreibbar ``` ### Große Dateien finden ```bash find /home -type f -size +100M find . -type f -exec du -h {} + | sort -rh | head -10 # Top 10 größte ``` ### Dateien nach Datum und Pfad ```bash find ~/Musik -type f \ -newermt "2025-04-01" \ -path "*/zzz Verschiedene/AlbumArt_*" \ -print ``` ### Dateien sichern ```bash find /etc -type f -mtime -1 -exec cp {} /backup/ \; ``` ### Backup-Kandidaten mit Datum ```bash find /backups -type f -name "*.tar.gz" \ -newermt "2023-08-01" ! -newermt "2023-08-31" ``` ### Logfile-Analyse ```bash find /var/log -type f -size +100M -newermt "2023-09-01" ``` ### Nur Dateien, nicht Verzeichnisse ändern ```bash find . -type f -exec chmod 644 {} + find . -type d -exec chmod 755 {} + ``` ## Best Practices und Fehler vermeiden ### Sicherheit beim Löschen ```bash # IMMER erst testen find . -name "*.tmp" -print find . -name "*.tmp" | wc -l find . -name "*.tmp" -exec echo rm {} + # Dann löschen find . -name "*.tmp" -delete ``` ### Leerzeichen in Dateinamen ```bash # RICHTIG: -print0 und xargs -0 find . -name "*.txt" -print0 | xargs -0 rm # RICHTIG: -exec mit + find . -name "*.txt" -exec rm {} + # FALSCH: Pipe ohne -print0 find . -name "*.txt" | rm # funktioniert nicht! ``` ### Trailing Slash bei -path ```bash find . -path "*/ordner/*" # Dateien IN ordner/ find . -path "*/ordner" # NUR ordner/ selbst ``` ### -delete Reihenfolge ```bash # RICHTIG: -type f VOR -delete find . -type f -name "*.tmp" -delete # FALSCH: kann Verzeichnisse löschen find . -name "*.tmp" -delete ``` ### Zu viele Argumente ```bash # FALSCH: kann "Argument list too long" geben find . -name "*.txt" -exec rm {} \; # RICHTIG: mit + find . -name "*.txt" -exec rm {} + # RICHTIG: mit xargs find . -name "*.txt" -print0 | xargs -0 rm ``` ## Alternative Tools - **fd** - moderner, schneller find-Ersatz mit besserer Syntax - **ripgrep (rg)** - für Textsuche in Dateien - **locate** - schnelle Dateinamensuche (nutzt Datenbank) Beispiel mit fd: ```bash fd "*.log" # Einfacher als find fd -t f -s +100M # Dateien > 100MB fd -e jpg -x convert {} ... # Mit exec ``` ## Siehe auch - [[ls]] - Dateien auflisten - [[grep]] - Textsuche in gefundenen Dateien - [[Dateiberechtigungen]] - Rechte und Eigentümer von Dateien - [[tar]] - Gefundene Dateien archivieren - [[rsync]] - Dateien synchronisieren - [[sed]] - Gefundene Dateien bearbeiten - [[awk]] - Ausgabe von find verarbeiten