11 KiB
fd - Dateien und Verzeichnisse schnell suchen
fd ist ein moderner, benutzerfreundlicher Ersatz für find. Die Standards
sind für die meisten interaktiven Suchen praktischer: Die Suche ist rekursiv,
Groß-/Kleinschreibung wird automatisch berücksichtigt, versteckte Dateien und
von Git ignorierte Dateien werden standardmäßig ausgelassen und die Ausgabe ist
farbig formatiert.
fd ist kein vollständiger Ersatz für jede komplexe find-Abfrage. Für
interaktive Dateisuche ist es aber oft kürzer und übersichtlicher.
Installation
Debian/Ubuntu:
sudo apt update
sudo apt install fd-find
Bei Debian und Ubuntu heißt das Programm je nach Distribution fdfind statt
fd:
fdfind --version
alias fd=fdfind # nur für die aktuelle Shell
Arch Linux:
sudo pacman -S fd
Fedora:
sudo dnf install fd-find
openSUSE:
sudo zypper install fd
Installation prüfen:
fd --version
fd --help
Grundsyntax
fd [OPTIONEN] [MUSTER] [SUCHPFAD...]
Ohne Argumente zeigt fd die Dateien und Verzeichnisse unterhalb des
aktuellen Verzeichnisses:
fd
fd README.md # nach README.md suchen
fd README ~/Projekte # in ~/Projekte suchen
fd 'backup.*' /var/tmp # Suchmuster angeben
Das Muster wird standardmäßig als regulärer Ausdruck interpretiert. Für eine
wortgetreue Suche kann -g (Glob) verwendet werden.
Nach Namen suchen
fd report # enthält "report" im Namen
fd -i report # ausdrücklich ohne Beachtung der Großschreibung
fd -g '*.pdf' # Glob-Muster, alle PDF-Dateien
fd -e pdf # nach der Endung pdf
fd -e jpg -e png # mehrere Endungen
fd -t f -e log # nur Dateien mit der Endung log
fd -t d config # nur Verzeichnisse mit "config" im Namen
fd -H '.env' # versteckte Dateien einbeziehen
Bei Globs müssen Wildcards quotiert werden, damit die Shell sie nicht vorab
expandiert. -e pdf ist meist angenehmer als -g '*.pdf', weil die Endung
ohne Punkt angegeben wird.
Reguläre Ausdrücke
fd '^README' # Namen, die mit README beginnen
fd 'v[0-9]+\.tar\.gz$' # z. B. v1.tar.gz
fd -I 'node_modules|target' # auch ignorierte Dateien suchen
fd -g 'bild-??.jpg' # Glob: genau zwei Zeichen vor .jpg
Mehrere Suchpfade sind möglich:
fd -t f -e md ~/Dokumente ~/Projekte
Suchbereich einschränken
fd -d 1 # nur direkt unterhalb des aktuellen Ordners
fd -d 3 -e log # höchstens drei Ebenen tief
fd -E node_modules # node_modules ausschließen
fd -E '*.min.js' # Dateien per Glob ausschließen
fd -E .git -E build # mehrere Ausschlüsse
fd -p 'src/lib' # Muster als vollständigen Pfad behandeln
fd -a report # absolute Pfade ausgeben
Standardmäßig werden versteckte Pfade, .gitignore-Treffer und .git
Verzeichnisse ausgelassen. Das Verhalten lässt sich mit diesen Optionen ändern:
fd -H pattern # versteckte Dateien einbeziehen
fd -I pattern # ignorierte Dateien einbeziehen
fd -u pattern # unbeschränkte Suche: versteckt + ignoriert
Dateitypen und Eigenschaften
fd -t f # reguläre Dateien
fd -t d # Verzeichnisse
fd -t l # symbolische Links
fd -t x # ausführbare Dateien
fd -t e # leere Dateien oder Verzeichnisse
fd -S +100M -t f # Dateien größer als 100 MB
fd -S -10k -t f # Dateien kleiner als 10 KB
fd --changed-within 7d # in den letzten sieben Tagen geändert
fd --changed-before 30d # vor mehr als 30 Tagen geändert
Größen-Suffixe sind unter anderem k, M, G und T. Zeitangaben können
beispielsweise 10m, 2h, 7d oder 1w sein. Die genaue Unterstützung hängt
von der installierten fd-Version ab; fd --help zeigt die verfügbaren
Optionen.
Ausgabe und Zählen
fd -l pattern # Long-Format wie bei ls
fd --color never pattern # ohne ANSI-Farbcodes
fd --print0 -e jpg # NUL-separiert, sicher für Sonderzeichen
fd -e log | wc -l # Treffer zählen
fd -e log | sort # Treffer sortieren
fd -e log | xargs -r grep -n ERROR
Für robuste Pipelines mit beliebigen Dateinamen immer --print0 zusammen mit
xargs -0 verwenden:
fd -0 -t f -e txt | xargs -0 -r wc -l
Befehle auf Treffer anwenden
-x führt einen Befehl für jeden Treffer aus. {} ist der Platzhalter für den
aktuellen Pfad:
fd -t f -e sh -x chmod +x '{}'
fd -t f -e log -x gzip '{}'
fd -t f -e txt -x grep -nH 'TODO' '{}'
-X übergibt alle Treffer gemeinsam an den Befehl. Das ist für Programme
geeignet, die mehrere Dateien in einem Aufruf verarbeiten können:
fd -t f -e jpg -X identify
fd -t f -e sh -X shellcheck
Vor einer Aktion zuerst einen Dry-Run ausführen:
fd -t f -e tmp -x echo rm -- '{}'
fd -t f -e jpg -x echo cp -- '{}' ~/Bilder/
-- trennt Optionen des externen Befehls vom Dateinamen. Die Quoting-Regeln
des Beispiels schützen auch Dateinamen mit Leerzeichen.
Dateien kopieren, verschieben und löschen
Löschen
# Treffer prüfen
fd -t f -e tmp
# Dry-Run
fd -t f -e tmp -x echo rm -- '{}'
# Tatsächlich löschen
fd -t f -e tmp -x rm -- '{}'
Leere Verzeichnisse:
fd -t d -e old -x echo rmdir -- '{}'
fd -t d -e old -x rmdir -- '{}'
rmdir löscht nur leere Verzeichnisse. Für nichtleere Verzeichnisse wäre
rm -r erforderlich und sollte besonders vorsichtig eingesetzt werden.
Kopieren
mkdir -p ~/Archiv/logs
fd -t f -e log -x echo cp -n -- '{}' ~/Archiv/logs/
fd -t f -e log -x cp -n -- '{}' ~/Archiv/logs/
cp -n verhindert das Überschreiben vorhandener Dateien. Für das Beibehalten
von Zeitstempeln und Berechtigungen kann cp -p ergänzt werden.
Verschieben
mkdir -p ~/Archiv/alte-logs
fd -t f -e log --changed-before 30d -x echo mv -i -- '{}' ~/Archiv/alte-logs/
fd -t f -e log --changed-before 30d -x mv -i -- '{}' ~/Archiv/alte-logs/
mv -i fragt vor dem Überschreiben nach. Mit mv -n werden bestehende
Zieldateien ohne Rückfrage nicht ersetzt.
Dateien gesammelt umbenennen
Für einfache Ersetzungen ist mv mit Shell-Parameterexpansion ausreichend.
Zuerst die geplanten Befehle anzeigen:
fd -t f -e jpeg -x sh -c 'for f do printf "mv -- %q %q\\n" "$f" "${f%.jpeg}.jpg"; done' sh
Wenn das Ergebnis stimmt:
fd -t f -e jpeg -x sh -c 'for f do mv -i -- "$f" "${f%.jpeg}.jpg"; done' sh
Weitere Beispiele für Namensänderungen:
# Suffix _alt ergänzen
fd -t f -e txt -x sh -c 'for f do mv -i -- "$f" "${f%.txt}_alt.txt"; done' sh
# Präfix backup- ergänzen
fd -t f -e conf -x sh -c 'for f do mv -i -- "$f" "$(dirname "$f")/backup-$(basename "$f")"; done' sh
Bei vielen Umbenennungen ist -x mit einer kleinen Shell-Schleife sicherer
als eine Pipe, weil Dateinamen nicht an Leerzeichen oder Zeilenumbrüchen
aufgeteilt werden.
Bulk-Bearbeitung von Dateien
Textdateien mit sed bearbeiten
# Erst anzeigen, welche Dateien betroffen sind
fd -t f -e conf -e cfg
# Dry-Run: Ausgabe prüfen, Dateien bleiben unverändert
fd -t f -e conf -e cfg -x sh -c 'for f do sed "s/alt/neu/g" "$f" > "$f.tmp" && diff -u "$f" "$f.tmp"; rm -- "$f.tmp"; done' sh
# In-place mit Backup-Datei
fd -t f -e conf -e cfg -x sed -i.bak 's/alt/neu/g' '{}'
Dateinamen mit Textsuche kombinieren
fd -t f -e md -x rg -nH 'TODO|FIXME' '{}'
fd -t f -e log -x sh -c 'for f do grep -l ERROR "$f"; done' sh
Dateien anhand des Namens einsortieren
mkdir -p ~/Sortiert/{pdf,bilder}
# Dry-Run
fd -t f -e pdf -x echo mv -i -- '{}' ~/Sortiert/pdf/
fd -t f -e jpg -e png -x echo mv -i -- '{}' ~/Sortiert/bilder/
# Ausführen
fd -t f -e pdf -x mv -i -- '{}' ~/Sortiert/pdf/
fd -t f -e jpg -e png -x mv -i -- '{}' ~/Sortiert/bilder/
Robuste Schleife mit NUL-Trennung
Wenn zusätzlich komplexe Shell-Logik oder mehrere Variablen benötigt werden, ist eine NUL-separierte Schleife eine gute Alternative:
while IFS= read -r -d '' file; do
printf 'Bearbeite: %s\n' "$file"
# command -- "$file"
done < <(fd -0 -t f -e txt)
Praktische Anwendungsfälle
# Die zehn größten Dateien unterhalb des aktuellen Ordners
fd -t f -S +1M -x du -h '{}' | sort -rh | head -10
# Alle ausführbaren Shell-Skripte finden
fd -t x -e sh
# Backups und temporäre Dateien ausschließen
fd -t f -E '*.bak' -E '*.tmp' -E .cache
# Markdown-Dateien der letzten Woche archivieren
fd -t f -e md --changed-within 7d -X tar -czf aktuelle-doku.tar.gz
# Prüfsummen für ISO-Dateien erzeugen
fd -t f -e iso -x sha256sum '{}'
Bei fd -X werden die Treffer als Argumente an tar übergeben. Für sehr
große Trefferlisten kann ein Befehl durch die Systemgrenze für Argumente
begrenzt sein; dann besser fd -0 mit xargs -0 oder tar-Optionen für
Dateilisten verwenden.
Vergleich mit find
| Aufgabe | find |
fd |
|---|---|---|
| Alle Logs finden | find . -type f -name '*.log' |
fd -t f -e log |
| Verzeichnis suchen | find . -type d -name 'src' |
fd -t d src |
| Tiefe begrenzen | find . -maxdepth 2 |
fd -d 2 |
| Verzeichnis ausschließen | find . -path './node_modules' -prune |
fd -E node_modules |
| Befehl ausführen | find . -type f -exec cmd {} + |
fd -t f -X cmd |
| Änderungszeit | find . -mtime -7 |
fd --changed-within 7d |
Komplexe Bedingungen nach Besitzer, Berechtigungen oder exakten Zeitstempeln
bleiben eine Stärke von find.
Wichtige Optionen
| Option | Bedeutung |
|---|---|
-t f |
nur reguläre Dateien |
-t d |
nur Verzeichnisse |
-t l |
nur symbolische Links |
-e EXT |
Dateiendung suchen |
-g |
Glob statt regulärem Ausdruck verwenden |
-i |
Groß-/Kleinschreibung ignorieren |
-H |
versteckte Dateien einbeziehen |
-I |
Git-ignorierte Dateien einbeziehen |
-u |
versteckte und ignorierte Dateien einbeziehen |
-d N |
maximale Tiefe |
-E PATH |
Pfad oder Muster ausschließen |
-a |
absolute Pfade ausgeben |
-0 / --print0 |
NUL-separierte Ausgabe |
-x CMD |
Befehl pro Treffer ausführen |
-X CMD |
Befehl mit allen Treffern ausführen |
-S SIZE |
nach Dateigröße filtern |
Best Practices
- Zuerst nur
fd ...ausführen und die Treffer kontrollieren. - Vor Änderungen
-x echo ...als Dry-Run verwenden. - Dateipfade immer quoten:
"$file"oder'{}'. - Bei Pipes für beliebige Dateinamen
-0undxargs -0verwenden. - Bei
rmundmv--vor dem Dateipfad setzen. - Für Lösch-, Verschiebe- und Umbenennungsaktionen Backups oder Versionskontrolle nutzen.
- Mit
fd --helpprüfen, welche Optionen die installierte Version unterstützt.
Siehe auch
- IT-Know-How/Linux/BASH Basics/find - Klassische Dateisuche mit find
- IT-Know-How/Linux/BASH Basics/grep - Textsuche in Dateien
- IT-Know-How/Linux/BASH Basics/sed - Textdateien gesammelt bearbeiten
- IT-Know-How/Linux/BASH Basics/awk - Textverarbeitung und Datenextraktion
- IT-Know-How/Linux/BASH Basics/Dateiberechtigungen - chmod und chown
- IT-Know-How/Linux/BASH Basics/rsync - Dateien synchronisieren