# 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: ```bash sudo apt update sudo apt install fd-find ``` Bei Debian und Ubuntu heißt das Programm je nach Distribution `fdfind` statt `fd`: ```bash fdfind --version alias fd=fdfind # nur für die aktuelle Shell ``` Arch Linux: ```bash sudo pacman -S fd ``` Fedora: ```bash sudo dnf install fd-find ``` openSUSE: ```bash sudo zypper install fd ``` Installation prüfen: ```bash fd --version fd --help ``` ## Grundsyntax ```bash fd [OPTIONEN] [MUSTER] [SUCHPFAD...] ``` Ohne Argumente zeigt `fd` die Dateien und Verzeichnisse unterhalb des aktuellen Verzeichnisses: ```bash 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 ```bash 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 ```bash 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: ```bash fd -t f -e md ~/Dokumente ~/Projekte ``` ## Suchbereich einschränken ```bash 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: ```bash fd -H pattern # versteckte Dateien einbeziehen fd -I pattern # ignorierte Dateien einbeziehen fd -u pattern # unbeschränkte Suche: versteckt + ignoriert ``` ## Dateitypen und Eigenschaften ```bash 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 ```bash 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: ```bash 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: ```bash 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: ```bash fd -t f -e jpg -X identify fd -t f -e sh -X shellcheck ``` Vor einer Aktion zuerst einen Dry-Run ausführen: ```bash 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 ```bash # 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: ```bash 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 ```bash 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 ```bash 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: ```bash 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: ```bash 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: ```bash # 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 ```bash # 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 ```bash 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 ```bash 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: ```bash while IFS= read -r -d '' file; do printf 'Bearbeite: %s\n' "$file" # command -- "$file" done < <(fd -0 -t f -e txt) ``` ## Praktische Anwendungsfälle ```bash # 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 1. Zuerst nur `fd ...` ausführen und die Treffer kontrollieren. 2. Vor Änderungen `-x echo ...` als Dry-Run verwenden. 3. Dateipfade immer quoten: `"$file"` oder `'{}'`. 4. Bei Pipes für beliebige Dateinamen `-0` und `xargs -0` verwenden. 5. Bei `rm` und `mv` `--` vor dem Dateipfad setzen. 6. Für Lösch-, Verschiebe- und Umbenennungsaktionen Backups oder Versionskontrolle nutzen. 7. Mit `fd --help` prü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