Pwd-Ergebnis in Bezug auf "~" machen?


28

pwd gibt mir

/data/users/me/some/random/folder

Gibt es eine einfache Möglichkeit zu erhalten

~/some/random/folder

aus pwd?


Ist das Leiten durch sed eine Option?
Matthew D. Scholefield

7
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:

dirs +0
~/some/random/folder

(Beachten Sie +0nicht-0 .)

Mit zsh:

dirs
~/some/random/folder

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:

$ pwd
/home/vagrant/foo/bar
$ echo ${PWD/#$HOME/'~'}
~/foo/bar

2
Dies funktioniert auch in kshund zsh.
mr.spuratic

1
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.


2
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
~

1
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:

pwd | sed 's,^/data/users/me,~,'

oder noch besser:

pwd | sed "s,^$HOME,~,"

1
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.
Mihai Danila
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.