ADMIN

2022

08

2022-07-28T12:00:00

Verzeichnisdienste und Benutzermanagement

PRAXIS

046

Open-Source-Tipp

Tools

Suche mit Fuzzy Finder

Schnüffelnase

Veröffentlicht in Ausgabe 08/2022 - PRAXIS

In diesem Monat geht es im Open-Source-Tipp weiter mit nützlichen Tools für die Kommandozeile. Diesmal dreht sich alles um den Fuzzy Finder, kurz fzf. Diesen können Sie innerhalb einer Shell als interaktiven Filter verwenden und zusammen mit anderen Kommandozeilentools einsetzen.

Wer viel auf der Kommandozeile arbeitet, der kennt natürlich das Konzept der Unix-Filter. Hierbei können Sie einzelne Tools miteinander kombinieren, sodass die Ausgabe eines Tools als Eingabe des nächsten dient. Möchten Sie beispielsweise in Erfahrung bringen, wie viele Prozesse auf Ihrem System aktuell aktiv sind, kombinieren Sie hierfür die beiden Tools ps und wc mit Hilfe einer Pipe miteinander:
ps -ef | wc -l
Fuzzy-Suche
Das gleiche Konzept lässt sich nun verwenden, um die Ausgabe von ps an das Tool fzf [1] weiterzuleiten, um den gewünschten Prozess sehr schnell mit Hilfe eines Fuzzy-Matching zu identifizieren:
ps -ef | fzf
Übergeben Sie also nun die Prozessliste an fzf, können Sie interaktiv in der Liste nach dem gewünschten Prozess suchen, indem Sie einfach anfangen, den Prozessnamen oder Teile hiervon einzutippen. Durch die Fuzzy-Suche, im Deutschen auch etwas umständlich als Unscharfe Suche [2] bezeichnet, zeigt fzf dann sämtliche Prozesse an, auf die die Suche passt. Dabei erscheinen die besten Ergebnisse natürlich zuerst in der Ergebnisliste, während weniger gute Matches weiter hinten in der Liste zu finden sind.
Wer viel auf der Kommandozeile arbeitet, der kennt natürlich das Konzept der Unix-Filter. Hierbei können Sie einzelne Tools miteinander kombinieren, sodass die Ausgabe eines Tools als Eingabe des nächsten dient. Möchten Sie beispielsweise in Erfahrung bringen, wie viele Prozesse auf Ihrem System aktuell aktiv sind, kombinieren Sie hierfür die beiden Tools ps und wc mit Hilfe einer Pipe miteinander:
ps -ef | wc -l
Fuzzy-Suche
Das gleiche Konzept lässt sich nun verwenden, um die Ausgabe von ps an das Tool fzf [1] weiterzuleiten, um den gewünschten Prozess sehr schnell mit Hilfe eines Fuzzy-Matching zu identifizieren:
ps -ef | fzf
Übergeben Sie also nun die Prozessliste an fzf, können Sie interaktiv in der Liste nach dem gewünschten Prozess suchen, indem Sie einfach anfangen, den Prozessnamen oder Teile hiervon einzutippen. Durch die Fuzzy-Suche, im Deutschen auch etwas umständlich als Unscharfe Suche [2] bezeichnet, zeigt fzf dann sämtliche Prozesse an, auf die die Suche passt. Dabei erscheinen die besten Ergebnisse natürlich zuerst in der Ergebnisliste, während weniger gute Matches weiter hinten in der Liste zu finden sind.
Haben Sie beispielsweise den Chrome-Browser installiert und tippen in der interaktiven fzf-Suche lediglich den String "oo" ein, erscheint der Prozess zwar in der Ergebnisliste, allerdings erst hinter sämtlichen "oom"-Prozessen. Starten Sie die Suche stattdessen mit dem Suchstring "goo", ist die Chance hoch, dass der Prozess direkt am Anfang der Liste steht.
Korrekte Syntax verwenden
Bei der Fuzzy-Suche lassen sich keine regulären Ausdrücke oder Wildcards verwenden. Stattdessen setzt fzf auf weitere Modi, die Sie nutzen können, um die Suche einzuschränken. Verwenden Sie den String "'goo", muss dieser String in exakt dieser Reihenfolge vorkommen. "^goo" hingegen verlangt, dass der String am Anfang des Suchergebnisses steht – also ähnlich wie bei den regulären Ausdrücken. Genauso verhält es sich auch mit dem String "goo$", der nun verlangt, dass das Suchergebnis mit diesem String aufhört.
Zum Ausschließen von Strings setzen Sie einfach ein "!" vor die entprechende Zeichenkette. Die einzelnen Varianten können Sie dabei auch kombinieren. Um also beispielsweise nach Ergebnissen zu suchen, die nicht mit dem String "goo" beginnen, verwenden Sie einfach den Suchbegriff "^!goo". Möchten Sie diesen String dagegen ausschließen, wenn dieser am Ende steht, so lautet der korrekte Suchbegriff "!goo$". Auch wenn es nützlich ist, diese unterschiedlichen Modi zur Verfügung zu haben, so reicht in den allermeisten Fällen jedoch die standardmäßige Fuzzy-Match-Variante aus, um an das gewünschte Ergebnis zu kommen.
Dateibrowser versus fzf
Stellen Sie sich vor, Sie haben irgendwo in den Tiefen Ihres Home-Verzeichnisses eine Datei mit dem Namen "0822.txt" liegen und möchten diese nun gerne mit Ihrem Lieblingseditor direkt aus der Shell heraus aufrufen. Natürlich könnten Sie hierfür den Dateibrowser Ihrer Wahl verwenden. Allerdings ist es dann recht mühselig, zuerst einmal in den Ordner zu wechseln, in dem sich die Datei befindet – wenn Sie denn überhaupt noch wissen, wie der Ordner heißt. Rufen Sie hingegen einfach das Kommando vim $(fzf) auf, können Sie einfach interaktiv in der Ergebnisliste die korrekte Datei auswählen, die fzf natürlich wieder problemfrei anhand einer Fuzzy-Suche identifiziert.
Shell-Integration
Sehr nützlich ist auch, dass fzf von Haus aus bestimmte Tastenkombinationen für die bash-, zsh- und fish-Shell anbietet, um so sehr bequem innerhalb eines Terminals arbeiten zu können. Die Navigation in tief verschachtelten Verzeichnissen bedeutet meistens viel Tipparbeit und bereitet wenig Freude. Mit fzf ändert sich dies jedoch, da eine Fuzzy-Suche nicht nur für die Kommandohistorie existiert, sondern eben auch für Datei- und Verzeichnisnamen.
Hierfür stellt fzf die Tastenkombinationen "CTRL+R", "CTRL+T" und "ALT+C" zur Verfügung. Erstere führt eine Fuzzy-Suche in der Kommandohistorie durch und fügt das Ergebnis dann in die Kommandozeile ein. Ähnlich sieht es mit "CTRL+T" aus, allerdings findet hier die Suche auf Basis von Datei- und Ordnernamen statt. Mittels "ALT+C" wechselt fzf dann auch direkt in das gesuchte Verzeichnis.
Die standardmäßigen Tastenkombinationen sind in key-bindings-Dateien definiert. Haben Sie beispielsweise das fzf-RPM-Paket auf einem Fedora-System installiert, liegen diese Dateien im Verzeichnis "/usr/share/fzf/shell/":
ls -l /usr/share/fzf/shell/
 
total 16
-rw-r--r--. 1 root root 3767 Apr 4 16:01 key-bindings.bash
-rw-r--r--. 1 root root 5727 Apr 4 16:01 key-bindings.fish
-rw-r--r--. 1 root root 3876 Apr 4 16:01 key-bindings.zsh
Bild 1: Mit Hilfe von fzf identifizieren Sie die korrekte Datei im Dateisystem sehr schnell.
Tastenkombinationen modifizieren
Möchten Sie die Tastenkombinationen anpassen oder neue hinzufügen, können Sie natürlich direkt diese Dateien editieren. Das hat aber den Nachteil, dass die Anpassungen nach einem Update des Pakets verloren sind. Insofern bietet es sich an, die Anpassung stattdessen in der Konfigurationsdatei der eingesetzten Shell durchzuführen. So bietet sich beispielsweise eine eigene Konfigurationsdatei für fzf an, die dann innerhalb der Konfiguration für die zsh einfach eingelesen wird:
grep fzf ~/.zshrc
 
[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
Die eigentliche Anpassung erfolgt dann über die Variablen
- FZF_CTRL_T_COMMAND
- FZF_CTRL_T_OPTS
- FZF_CTRL_R_OPTS
- FZF_ALT_C_COMMAND und
- FZF_ALT_C_OPTS.
Die key-bindings Dateien dienen hierfür als gutes Beispiel.
Bild 2: fzf kann eine Fuzzy-Suche für sämtliche Prozesse eines Systems durchführen.
Trigger-Sequenz zur Fuzzy-Suche
Sehr interessant ist auch, dass fzf eine Trigger-Sequenz für die Fuzzy-Suche auf der Shell bereitstellt. Hört sich kompliziert an, ist aber ganz einfach und sehr elegant. Sobald Sie die Sequenz "**" gefolgt von einem "<Tab>" verwenden, weisen Sie fzf an, eine Suche nach Datei- und Verzeichnisnamen zu starten und das Ergebnis dann als Argument zu einem Kommando zu verwenden:
vim **<Tab>
Das Ganze funktioniert übrigens auch mit dem SSH-Kommando, um nach IP-Adressen und Hostnamen zu suchen. Als Referenz dient in diesem Fall die SSH-Konfiguration und die Datei "/etc/hosts":
ssh **<Tab>
Die Trigger-Sequenz können Sie bei Bedarf ebenfalls anpassen. Möchten Sie statt der Zeichenfolge "**" lieber "~~" verwenden, ist hierfür lediglich die Variable "FZF_COMPLETION_TRIGGER" anzupassen. Ganz ähnlich sieht es für das das kill-Kommando aus. Hierfür können Sie sogar komplett auf die Trigger-Sequenz verzichten. Rufen Sie einfach das kill-Kommando auf, eventuell mit dem gewünschten Signal, und fzf führt eine Suche in sämtlichen Prozessen des Systems durch:
kill -1 <Tab>
Link-Codes
Layout anpassen
In der Standardkonfiguration verwendet fzf den kompletten Bildschirm für die Suche. Dies ist meist unpraktikabel. Zum Glück können Sie das Layout aber selbst festlegen und die gewünschten Optionen dann einfach als Teil der Variable "FZF_DEFAULT_OPTS" bei jedem Aufruf von fzf mit übergeben. So bieten sich beispielsweise die folgenden Einstellungen an:
grep FZF_DEFAULT_OPTS ~/.fzf.zsh
 
export FZF_DEFAULT_OPTS='--height 40% --layout=reverse --border'
Damit verwendet das fzf-Fenster lediglich eine Höhe von 40 Prozent des Bildschirms, das Fenster bekommt einen Rahmen und die Suche startet direkt unterhalb des Cursors, anstatt vom unteren Ende des Fensters. Weitere Optionen zur Anpassung des Layouts entnehmen Sie wie gewohnt der fzf-Hilfeseite (man fzf).
Fazit
Das Tool fzf ist extrem hilfreich, wenn Sie viel innerhalb einer Shell arbeiten. Mit Hilfe einer Fuzzy-Suche ist es ein Leichtes, schnell und ohne viel Tipparbeit in die richtigen Verzeichnisse zu wechseln oder Dateien aufzurufen. Auch die Integration mit anderen Kommandozeilentools spart eine Menge Zeit, weil Sie einfach viel schneller an die gesuchten Informationen gelangen.
(dr)