Schneller Verzeichniswechsel im Terminal

Fr, 12. Februar 2021, Ralf Hersel

Beginnen möchte ich diesen Artikel mit einer Frage: 'Welches ist der häufigste Befehl, den du im Terminal verwendest?' Lasst mich raten, es ist 'cd' für den Verzeichniswechsel. Seit meinen Anfängen mit der Arbeit im Terminal hat mich der mühsame Verzeichniswechsel immer gestört. Ich konnte nie glauben, dass es bei den fast unendlichen Terminalbefehlen keine Möglichkeit gibt, schnell und direkt zu einem Verzeichnis zu wechseln, ohne den Baum herauf oder hinunter hangeln zu müssen. Nach vielen Jahre habe ich endlich eine gute Lösung gefunden.

Die geneigte Leserin mag verwundert die Stirn runzeln, weil sie darin kein Problem sieht. Die meisten Dateimanager (Nautilus, Nemo, Thunar, ..) bieten die Möglichkeit, das aktuelle Verzeichnis per 'Im Terminal öffnen' anzusteuern. Ich suchte jedoch ein Verfahren innerhalb des Terminals, ohne eine zweite Anwendung zu bemühen.

Wie weiss man überhaupt, ob 'cd' der häufigste Befehl im Termin ist? Das kann man mit diesem Kommando ermitteln. Das Ergebnis ist nicht zwingend eindeutig; vielleicht kommen die Befehle 'apt, cat, find, git, ..' häufiger vor, aber 'cd' findet sich bestimmt in den oberen Rängen. Probiert es aus:

history |awk '$1=" "' |sort |uniq -c |sort -nr

Die normale Navigation zwischen Verzeichnissen findet in allen Shells (bash, fish, zsh, ..) über den Befehl 'cd directory_name' statt. Damit bewegt man sich entlang des hierarchischen Baums der Verzeichnisse (Befehl: 'tree' um das zu verdeutlichen). 'cd' bietet zwar Completion (cd doc <tab>), jedoch nur über die nächste Ebene. Einen Schritt weiter geht die Z-Shell; dort ist eine Suche über die gesamte Hierarchie möglich: 'cd a/b/c', wobei die Verzeichnisse anhand ihrer ersten Buchstaben gesucht werden. Konkret: 'cd Doku/Rech/2020' findet: '~/Dokumente/Rechnungen/2020'. Das ist schon einmal ziemlich gut, aber noch nicht das erwünschte Ziel. Die Eingaben von 'cd 2020' sollte ausreichen.

Einen Schritt weiter gehen die auf das Ziel spezialisierten Skripte, wie zum Beispiel:

  1. export CDPATH=[Verzeichnisliste getrennt mit : ] in der .bashrc oder .zshrc
    Beispiel: export CDPATH=/home/ralf/Development/python/:/home/ralf/Musik/

  2. Das Skript 'fcd.sh' - https://forum.ubuntuusers.de/topic/in-ein-verzeichnis-springen/
  3. pushd und popd - https://en.wikipedia.org/wiki/Pushd_and_popd
  4. autojump - https://github.com/wting/autojump

Ich habe alle Lösungen ausprobiert - keine davon erfüllt meine Anforderungen. Vor ein paar Tagen habe ich begonnen, eine eigene Variante zu entwickelt: 'cdx directory_name'. Im Terminal funktioniert das ganz gut:

cd $(echo "`find $(pwd) -maxdepth 5 -type d -not -path '*/\.*' | grep -i 'Musik' | head -1`")

Der Befehl erstellt mit 'find' eine Liste aller Verzeichnispfade, sucht dann mit 'grep' nach dem Verzeichnis 'Musik' (oder Abkürzungen davon), holt aus der Ergebnisliste den ersten Treffer und führt ein 'cd' darauf aus. Leider ist es mir bisher nicht gelungen, diesen Befehl als Alias oder Function in die .bashrc einzufügen.

Verzweifelt an dieser Stelle nicht, denn die Lösung ist nahe; sie kommt von Rupa aus Philadelphia und heisst 'z'. Das Shell-Skript 'z.sh' kopiert man in ein beliebiges Verzeichnis und trägt folgenden Befehl in die $HOME/.bashrc oder $HOME/.zshrc ein:

. /path/to/z.sh

Nach dem Neustart eines evtl. bereits offenen Terminal kann 'z' verwendet werden. Das Skript legt bei jedem Aufruf von 'cd pfad' einen Eintrag in der Datei '.z' an und versieht diese mit einer Gewichtung. Häufig angesprungene Verzeichnisse bleiben in der Liste erhalten, während seltene irgendwann aus der Liste herausfallen. Die Voraussetzung für das Funktionieren von 'z' ist somit, dass ein Verzeichnis mindestens einmal mit 'cd' aufgerufen wurde. Die Verwendung von 'z' ist denkbar einfach, nämlich: z Verzeichnisname (oder Teile davon). Hier ein Bespiel:

Der Befehl 'z 20' springt sofort in das Verzeichnis '~/Dokumente/Rechnungen/2020'. Falls sich jemand über den Befehel 'h' wundert; das ist nur ein Alias auf 'cd ~' in meiner .bashrc. Beim zweiten Beispiel springt 'z mus' in das Verzeichnis '~/dev/youplay/music'. Falls der Suchbegriff nicht eindeutig ist, wird das Verzeichnis mit der höheren Gewichtung aus der Datei '.z' angesprungen. Wenn man 'z' ohne Parameter aufruft, wird die Liste der gewichteten Verzeichnisse angezeigt.

Das Skript 'z.sh' hat noch mehr auf Lager, wie man in der Quelle nachlesen kann:

Quelle: https://github.com/rupa/z