363 lines
7.5 KiB
Markdown
363 lines
7.5 KiB
Markdown
# 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
|