In diesem Fall empfehle ich dringend , den resultierenden Befehl anders zu benennen als pwd. Andernfalls brechen Sie Skripts, deren Ausgabe voraussichtlich in Kontexten verwendet wird, in denen keine Tilde-Erweiterung ausgeführt wird.
Charles Duffy
Antworten:
25
Wenn Sie Bash verwenden, hat das dirseingebaute Programm das gewünschte Verhalten:
Um genau zu sein, müssen wir zuerst den Verzeichnisstapel löschen, sonst wird dirsder gesamte Inhalt gedruckt:
dirs -c; dirs
Oder mit zsh‚s printbuiltin:
print -rD $PWD
oder
print -P %~
(Diese Option aktiviert die Eingabeaufforderungserweiterung . %~In wird $PS1auf das aktuelle Verzeichnis erweitert und durch $HOMEersetzt. Sie verarbeitet ~jedoch auch andere benannte Verzeichnisse wie das Basisverzeichnis anderer Benutzer oder benannte Verzeichnisse , die Sie selbst definieren.)
Ich wechsle die ganze Zeit zwischen bash und zsh. Leider zwingt mich diese Lösung, mich an den Unterschied zwischen den Muscheln zu erinnern und auch zu überprüfen, wo ich mich gerade befinde. Die Antwort von @Bichoy ist für diese beiden Shell-Agnostiker.
28.
17
Sie können die Funktion zum Ersetzen variabler Bash-Teilzeichenfolgen verwenden:
Obwohl ich diese Antwort positiv bewertet habe, weil dies der einfachste Weg ist, gibt es hier eine kleine Einschränkung: In / tmp / home / username wird / tmp ~ zurückgegeben. Ich kann kein Caret-Zeichen vor $ HOME einfügen, um dieses Problem zu beheben. Wenn Sie eine perfekte Lösung benötigen, verwenden Sie diese nicht ...
0fnt
1
@ user18151, als Sie für diesen Hinweis. Ich habe meine Antwort auf die ${string/#substring/replacement}Version ersetzt, um dieses Verhalten zu verhindern.
Nykakin,
1
@ mr.spuratic es ist nur richtig (außer für die Verwendung von echo) in zsh. In anderen Shells $HOMEwürde das als Muster behandelt und das Ganze unter Split + Glob.
Stéphane Chazelas
Die Flucht vor der Tilde ('~') hat es geschafft. Beachten Sie, dass \ ~ auch funktioniert. Dies ist praktisch, wenn bereits im '-Kontext: zBPROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"'
Atafar
7
Verwenden von sed:
pwd | sed "s|^$HOME|~|"
Die Idee ist, jedes Zeichen zu verwenden, das in einem sedAusgangsverzeichnispfad weniger wahrscheinlich als Begrenzer in regulären Ausdrücken vorkommt. Im obigen Beispiel verwende ich |.
Das Gute an dieser Technik ist, dass sie tatsächlich schalenunabhängig ist.
Sie können auch einen Alias verwenden pwd, /bin/pwd | sed "s|$HOME|~|"um dieses Verhalten in anderen möglicherweise verwendeten Skripten abzurufen pwd.
Sie müssen den ^Anker in Ihre Regex aufnehmen. Andernfalls ist es möglich (jedoch unwahrscheinlich), ein Segment in der Mitte des Pfades zu ersetzen.
Sildoreth
Eigentlich sollte der reguläre Ausdruck wie folgt aussehen "s|^/home/user\(/.*\)\?$|~\1|". Ansonsten passt es andere Pfade der Nutzer , wenn ihre Namen wie sind user1, user2, user3und Sie passen einfachuser
AVP
3
tilde=\~${PWD#~}
Ich denke das ist was du willst?
Das Schöne an der Tilde ist, dass sie nicht zitiert werden muss, wenn sie als Muster erweitert wird. Auf $HOMEdie gleiche Weise ohne Anführungszeichen zu verwenden, würde zu unvorhersehbaren Ergebnissen führen, da jedes seiner konstituierenden Zeichen Musterzeichen sein kann und daher möglicherweise nicht immer das erwartete Ergebnis liefert.
Die Tilde-Erweiterung soll jedoch immer so erfolgen, als ob sie das Ergebnis einer angegebenen Erweiterung wäre, und daher sind ihre Ergebnisse vorhersehbar. Dies scheint in praktisch jeder Shell zuzutreffen, die ich casemit den bemerkenswerten Ausnahmen beider ksh93und mkshaus welchen Gründen auch immer auf Muster und Parametermuster getestet habe - keines davon scheint den zitierten Aspekt der Tilde in dieser Eigenschaft zu berücksichtigen .
Eine weitere nette Sache dabei ist, dass Sie neu definieren können $HOME, um jedes Verzeichnis auf dieselbe Weise zu behandeln. Beispielsweise:
cd ~
HOME=/some/prefix/I/would/like/to/trim
#or, perhaps more usefully, some scripted means of arriving at same
tilde=\~${OLDPWD#~}
HOME=$PWD
Hier ist ein weiteres Beispiel:
set 1 2 3 4 5 \~
cd ~; cd -; HOME= IFS=/
for d do shift
HOME=${*#~/}/$d
set ~ "$d" $HOME
done; cd -; HOME=$PWD
printf %s\\n "$@"
5/4/3/2/1/2/3/4/5/~/1/2/3/4/5/~
~
5
4
3
2
1
2
3
4
5
~
1
2
3
4
5
~
Das ist ein wirklich interessanter Ansatz. Aber es wird davon ausgegangen, dass $PWDdas unter ist $HOME. Sie könnten dieselbe Idee in Kombination mit der Mustersubstitution verwenden, um sie allgemeiner zu gestalten. Wie ${PWD/#~/\~}gehts
Mikel
1
Eigentlich ist Nykakins Antwort im Grunde das.
Mikel
0
Sie können versuchen, das unerwünschte Teil durch Folgendes zu ersetzen sed:
Sie müssen den ^Anker verwenden, um sicherzustellen, dass nur Übereinstimmungen am Anfang des Verzeichnispfads ersetzt werden. Außerdem müssen Sie nicht verwenden, gda der Befehl höchstens ein Vorkommen ersetzen soll.
Sildoreth
Vielen Dank. Ich lerne diese Dinge immer noch und dein Kommentar ist wirklich hilfreich.
user1403360
Problematisch, wenn mein Home-Verzeichnis /home/aliceund mein aktuelles Verzeichnis ist /home/aliceinchains. Wenn ich das Feature jedoch nur dann verwenden möchte, wenn ich weiß, dass ich mein Basisverzeichnis oder eines seiner Unterverzeichnisse bin, sollte es funktionieren.
pwd
. Andernfalls brechen Sie Skripts, deren Ausgabe voraussichtlich in Kontexten verwendet wird, in denen keine Tilde-Erweiterung ausgeführt wird.Antworten:
Wenn Sie Bash verwenden, hat das
dirs
eingebaute Programm das gewünschte Verhalten:(Beachten Sie
+0
nicht-0
.)Mit
zsh
:Um genau zu sein, müssen wir zuerst den Verzeichnisstapel löschen, sonst wird
dirs
der gesamte Inhalt gedruckt:Oder mit
zsh
‚sprint
builtin:oder
(Diese Option aktiviert die Eingabeaufforderungserweiterung .
%~
In wird$PS1
auf das aktuelle Verzeichnis erweitert und durch$HOME
ersetzt. Sie verarbeitet~
jedoch auch andere benannte Verzeichnisse wie das Basisverzeichnis anderer Benutzer oder benannte Verzeichnisse , die Sie selbst definieren.)quelle
Sie können die Funktion zum Ersetzen variabler Bash-Teilzeichenfolgen verwenden:
quelle
ksh
undzsh
.${string/#substring/replacement}
Version ersetzt, um dieses Verhalten zu verhindern.echo
) inzsh
. In anderen Shells$HOME
würde das als Muster behandelt und das Ganze unter Split + Glob.PROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"'
Verwenden von
sed
:Die Idee ist, jedes Zeichen zu verwenden, das in einem
sed
Ausgangsverzeichnispfad weniger wahrscheinlich als Begrenzer in regulären Ausdrücken vorkommt. Im obigen Beispiel verwende ich|
.Das Gute an dieser Technik ist, dass sie tatsächlich schalenunabhängig ist.
Sie können auch einen Alias verwenden
pwd
,/bin/pwd | sed "s|$HOME|~|"
um dieses Verhalten in anderen möglicherweise verwendeten Skripten abzurufenpwd
.quelle
^
Anker in Ihre Regex aufnehmen. Andernfalls ist es möglich (jedoch unwahrscheinlich), ein Segment in der Mitte des Pfades zu ersetzen."s|^/home/user\(/.*\)\?$|~\1|"
. Ansonsten passt es andere Pfade der Nutzer , wenn ihre Namen wie sinduser1
,user2
,user3
und Sie passen einfachuser
Ich denke das ist was du willst?
Das Schöne an der Tilde ist, dass sie nicht zitiert werden muss, wenn sie als Muster erweitert wird. Auf
$HOME
die gleiche Weise ohne Anführungszeichen zu verwenden, würde zu unvorhersehbaren Ergebnissen führen, da jedes seiner konstituierenden Zeichen Musterzeichen sein kann und daher möglicherweise nicht immer das erwartete Ergebnis liefert.Die Tilde-Erweiterung soll jedoch immer so erfolgen, als ob sie das Ergebnis einer angegebenen Erweiterung wäre, und daher sind ihre Ergebnisse vorhersehbar. Dies scheint in praktisch jeder Shell zuzutreffen, die ich
case
mit den bemerkenswerten Ausnahmen beiderksh93
undmksh
aus welchen Gründen auch immer auf Muster und Parametermuster getestet habe - keines davon scheint den zitierten Aspekt der Tilde in dieser Eigenschaft zu berücksichtigen .Eine weitere nette Sache dabei ist, dass Sie neu definieren können
$HOME
, um jedes Verzeichnis auf dieselbe Weise zu behandeln. Beispielsweise:Hier ist ein weiteres Beispiel:
quelle
$PWD
das unter ist$HOME
. Sie könnten dieselbe Idee in Kombination mit der Mustersubstitution verwenden, um sie allgemeiner zu gestalten. Wie${PWD/#~/\~}
gehtsSie können versuchen, das unerwünschte Teil durch Folgendes zu ersetzen
sed
:oder noch besser:
quelle
^
Anker verwenden, um sicherzustellen, dass nur Übereinstimmungen am Anfang des Verzeichnispfads ersetzt werden. Außerdem müssen Sie nicht verwenden,g
da der Befehl höchstens ein Vorkommen ersetzen soll./home/alice
und mein aktuelles Verzeichnis ist/home/aliceinchains
. Wenn ich das Feature jedoch nur dann verwenden möchte, wenn ich weiß, dass ich mein Basisverzeichnis oder eines seiner Unterverzeichnisse bin, sollte es funktionieren.