Ich suche einen eleganten Einzeiler (z. B. awk
), der eine Zeichenfolge eines Unix-Pfads mit dem ersten Zeichen jeder übergeordneten / mittleren Ebene, aber dem vollständigen Basisnamen verkürzt. Einfacher anhand von Beispielen zu zeigen:
/path/to/file
→/p/t/file
/tmp
→/tmp
/foo/bar/.config/wizard_magic
→/f/b/./wizard_magic
/foo/bar/.config/wizard_magic
→/f/b/.c/wizard_magic
In Anbetracht der guten Punkte von @ MichaelKjörling und @ChrisH unten zeigt dieses Beispiel, wie wir die ersten beiden Zeichen anzeigen können, wenn das erste Zeichen ein Punkt ist.
/f/b/.c/wizard_magic
. Der Punkt ist in einem bestimmten Verzeichnis häufig so häufig, dass er nur einen sehr kleinen Hinweis darauf gibt, wo Sie suchen sollten..
bedeutet dies normalerweise nur "aktuelles Verzeichnis". Dies/f/b/./wizard_magic
ist dasselbe wie,/f/b/wizard_magic
weil das./
Pfadelement zu einem leeren Pfadelement komprimiert wird.Antworten:
Für diese Testdatei:
Die Abkürzungen können mit diesem awk-Code generiert werden:
Edit1: Verwenden von zwei Zeichen für Punktnamen
In dieser Version werden Verzeichnisnamen auf ein Zeichen
.
abgekürzt, mit Ausnahme von Namen, die mit zwei Zeichen abgekürzt werden:Wie es funktioniert
-F/
Dies weist awk an, bei der Eingabe einen Schrägstrich als Feldtrennzeichen zu verwenden.
for (i=1;i<NF;i++) $i=substr($i,1,1)
Dies durchläuft jedes Feld mit Ausnahme des letzten und ersetzt es durch nur das erste Zeichen.
EDIT1: In der überarbeiteten Version geben wir die Länge des Teilstrings 2 an, wenn das Feld mit beginnt
.
.1
Dies weist awk an, die überarbeitete Zeile zu drucken.
OFS=/
Dies weist awk an, bei der Ausgabe einen Schrägstrich als Feldtrennzeichen zu verwenden.
quelle
‥
Trennzeichens:awk -F/ '{for (i=1;i<NF;i++) $i=substr($i,1,1+($i~/^[.]/))(i==1||length($i)<2?"":"‥")} 1' OFS=/ <<<$PWD
gibt:/foo/bar/.config/wizard_magic
→/f‥/b‥/.c‥/wizard_magic
Ziemlich einfach in sed (vorausgesetzt, die Dateinamen enthalten keine Zeilenumbrüche):
In awk weniger einfach, weil es keine Rückreferenzen gibt (außer in Gawk, aber mit einer ungeschickten Syntax):
In zsh (mit dem Pfad in
$full_path
):quelle
\1
im Ersetzungsstring hat einen Verweis auf eine Capture - Gruppe im Muster bedeuten. Eine Rückreferenz ist eine Rückreferenz, unabhängig davon, wo Sie sie verwenden.Sie können es tun wie:
und hier ist ein
sed
:das kommt ziemlich nahe daran, all die gleichen Dinge zu tun, die die Funktion unten macht. Es wird nicht mit Tildes abgekürzt oder
$PWD
für einen führenden Nicht-Schrägstrich in den Kopf eingefügt, wie dies bei der Funktion der Fall ist (und tatsächlich wird der führende Schrägstrich nie gedruckt), aber das könnte später behandelt werden. Es verarbeitet Nullpfadkomponenten und Einzelpunkte und beseitigt..
Fälle.Bei gleichem
man
Pfad wiecd
oben wird Folgendes gedruckt:Außerdem werden ein oder zwei zusätzliche führende Punkte für jede Pfadkomponente gedruckt, die mit einer solchen beginnt und nicht nur aus einem oder zwei Punkten besteht.
Sie haben gefragt, ob Sie mehr als das eine Zeichen für eine Pfadkomponente tun möchten, beginnend mit a
.
. Um dies zu tun, dachte ich, dass jede Komponente sowieso individuelle Aufmerksamkeit benötigen würde, und weil ich neugierig war, versuchte ich mich daran, einen kanonischen Pfad ohne das Änderungsverzeichnis auszuarbeiten. Nach einigem Ausprobieren entschied ich schließlich, dass der einzige Weg, es richtig zu machen, darin bestand, es zweimal zu tun - vorwärts und rückwärts:Damit wird niemals das Verzeichnis geändert oder versucht, die Existenz einer Pfadkomponente zu bestätigen, sondern es werden wiederholte
/
Trennzeichen gequetscht und/./
Einzelpunktkomponenten vollständig gelöscht und/../
Doppelpunktkomponenten entsprechend verarbeitet.Wenn
$IFS
ein Nicht-Leerzeichen festgelegt ist , führt eine Folge von zwei oder mehr$IFS
Zeichen zu einem oder mehreren Nullfeldern. Daher werden mehrere aufeinanderfolgende Schrägstriche zu Argumenten mit Nullwerten verarbeitet. Gleiches gilt für eine$IFS
Hauptfigur. und so, wenn geteilt wirdset -- $1
, wenn das Ergebnis$1
null ist, dann begann es mit einem Schrägstrich, sonst,${1:+$PWD}
wenn es nicht null ist, dann füge ich ein$PWD
. Mit anderen Worten, wenn das erste Argument nicht mit einem Schrägstrich beginnt, wird es$PWD
vorangestellt. Das ist so nah wie die Pfadvalidierung .Andernfalls
for
invertiert die erste Schleife rekursiv die Reihenfolge der Pfadkomponenten wie:... dabei werden Einzelpunkt- oder Nullkomponenten ignoriert, und
..
das tut es auch ...... der zweite Durchgang kehrt diesen Effekt um und drückt dabei jede Komponente entweder auf 2 Punkte + Zeichen oder 1 Punkt + Zeichen oder Zeichen .
es sollte also unabhängig von der Existenz zu einem kanonischen Weg führen.
Ich habe ein wenig zur zweiten Schleife addiert / subtrahiert. Jetzt
set
s weniger oft (nur einmal für jede[!./]*
Komponente) und Kurzschlüssecase
Muster Auswertungen der meiste Zeit (dank das oben genannte Muster) und enthält eine Tail-Call - Match-Auswertung gegen~
. Wenn alle oder ein führender Teil (wie auf ganze Komponenten aufgeteilt) des endgültig kanonischen Pfades übereinstimmen können~
, wird das Übereinstimmungsbit entfernt und ein Literal~
ersetzt. Um dies zu tun, musste ich neben dem abgekürzten Pfad auch eine vollständige Kopie des Pfads pflegen (da es~
wahrscheinlich nicht sehr hilfreich wäre, den abgekürzten Pfad mit zu verknüpfen) , und dies wird beibehalten$3
. das Letztewhile
Der Schleifenzweig wird nur ausgeführt, wenn er~
als Teilmenge von übereinstimmt$3
.Wenn Sie es mit
set -x
aktiviertem Trace ausführen, können Sie beobachten, wie es funktioniert.quelle
Das "fischige" Zsh-Thema von Oh My Zsh enthält ein Perl-Snippet, das genau das tut, was Unicode-Unterstützung bietet:
quelle
Möchten Sie einen Kurznamen haben oder ihn für Ihre Befehlszeile verwenden?
Für die Befehlszeile habe ich folgende Vorschläge:
Hilft Ihnen die Dateivervollständigung in Ihrer Shell nicht?
Manchmal hat man Glück und muss nichts Besonderes tun:
Wenn Sie nur einige Verzeichnisse haben, an denen Sie interessiert sind, können Sie Aliase verwenden:
Oder Sie können Variablen für Ihre Lieblingsverzeichnisse einrichten
Ich denke, diese Optionen sind sinnvoller, als zu versuchen, dies mit einer in .bashrc (oder .profile) definierten Funktion wie zu lösen
und Aufruf dieser Funktion x mit Leerzeichen zwischen Ihren Buchstaben:
quelle