Files
it-know-how/Linux/BASH Basics/find.md
T
2026-09-02 16:32:50 +02:00

7.7 KiB

find - Dateien und Verzeichnisse suchen

Der Befehl find durchsucht Verzeichnisse rekursiv nach Dateien oder Ordnern anhand verschiedener Kriterien.

Grundsyntax

find [Pfad] [Suchkriterien] [Aktionen]

Suchkriterien

Nach Namen suchen

find . -name "datei.txt"       # exakte Übereinstimmung
find . -iname "datei.txt"      # case-insensitive
find . -name "*.log"           # mit Wildcards

Nach Dateityp suchen

find . -type f    # nur Dateien
find . -type d    # nur Verzeichnisse
find . -type l    # symbolische Links

Nach Dateigröße suchen

find . -size +10M   # größer als 10 MB
find . -size -100k  # kleiner als 100 KB
find . -size 0      # leere Dateien

Nach Berechtigungen suchen

find . -perm 644       # Dateien mit Rechten 644
find . -user alice     # Dateien von User "alice"
find . -group admins   # Dateien von Gruppe "admins"

Suchtiefe begrenzen

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)

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:

find . -mtime +7 -mtime -30

Absolute Zeitangaben (Datum, GNU find)

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

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)

find . -type f -size +1M -mtime -7

Dateien größer als 1 MB UND in den letzten 7 Tagen geändert.

ODER-Verknüpfung

find . -type f \( -name "*.jpg" -o -name "*.png" \)

Alle .jpg ODER .png Dateien.

Negation

find . -type f ! -iname "*.mp3"

Alle Dateien, die NICHT auf .mp3 enden.

Mehrere Endungen ausschließen:

find . -type f ! \( -iname "*.mp3" -o -iname "*.flac" \)

Aktionen auf gefundene Dateien

Anzeigen

find . -name "*.log" -print     # Standard
find . -name "*.log" -ls        # mit Details

Dateien löschen

Grundprinzip: Immer erst testen, dann löschen!

# 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:

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):

find . -name "*.tmp" -print0 | xargs -0 rm

Mit -exec Befehle ausführen

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

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)

find ~/Musik -type f -path "*/zzz Verschiedene/AlbumArt_*"

-path verwendet Shell-Wildcards (Globs), nicht reguläre Ausdrücke.

Mit -regex (Reguläre Ausdrücke)

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

find /tmp -type f -mtime +7 -delete

Leere Dateien/Verzeichnisse finden

find . -type f -empty   # leere Dateien
find . -type d -empty   # leere Ordner

Dateien mit falschen Rechten

find / -type f -perm -o+w    # weltweit schreibbar

Große Dateien finden

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

find ~/Musik -type f \
  -newermt "2025-04-01" \
  -path "*/zzz Verschiedene/AlbumArt_*" \
  -print

Dateien sichern

find /etc -type f -mtime -1 -exec cp {} /backup/ \;

Backup-Kandidaten mit Datum

find /backups -type f -name "*.tar.gz" \
  -newermt "2023-08-01" ! -newermt "2023-08-31"

Logfile-Analyse

find /var/log -type f -size +100M -newermt "2023-09-01"

Nur Dateien, nicht Verzeichnisse ändern

find . -type f -exec chmod 644 {} +
find . -type d -exec chmod 755 {} +

Best Practices und Fehler vermeiden

Sicherheit beim Löschen

# 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

# 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

find . -path "*/ordner/*"   # Dateien IN ordner/
find . -path "*/ordner"     # NUR ordner/ selbst

-delete Reihenfolge

# RICHTIG: -type f VOR -delete
find . -type f -name "*.tmp" -delete

# FALSCH: kann Verzeichnisse löschen
find . -name "*.tmp" -delete

Zu viele Argumente

# 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:

fd "*.log"                    # Einfacher als find
fd -t f -s +100M              # Dateien > 100MB
fd -e jpg -x convert {} ...   # Mit exec

Siehe auch