Jeśli masz zamiar to zrobić, zdecydowanie polecam nazwać wynikowe polecenie na coś innego niż pwd. W przeciwnym razie złamiesz skrypty, które oczekują użycia swoich wyników w kontekstach, które nie wykonują interpretacji tyldy.
Charles Duffy
Odpowiedzi:
25
Jeśli używasz bash, to dirswbudowane ma pożądane zachowanie:
Aby być dokładnie, najpierw musimy wyczyścić stos katalogów, w przeciwnym dirsrazie wydrukujemy całą zawartość:
dirs -c; dirs
Lub z zsh„s printwbudowanego polecenia:
print -rD $PWD
lub
print -P %~
(ten włącza szybkie rozszerzanie . %~in $PS1rozwija się do bieżącego katalogu z $HOMEzastąpionym przez, ~ale obsługuje również inne nazwane katalogi, takie jak katalog domowy innych użytkowników lub nazwane katalogi , które sam definiujesz).
Cały czas przełączam się między bash a zsh. Niestety to rozwiązanie zmusza mnie do zapamiętania różnicy między powłokami, a także do zapamiętania (sprawdzenia), gdzie aktualnie jestem. Odpowiedź @Bichoy jest niezależna od powłoki dla tych dwóch.
avp
18
Możesz użyć funkcji zamiany podciągów zmiennych Bash:
Chociaż głosowałem za odpowiedzią na tę odpowiedź, ponieważ jest to najprostszy sposób, jest tutaj małe zastrzeżenie: wewnątrz / tmp / home / nazwa użytkownika, to zwróci / tmp ~. Nie mogę znaleźć sposobu, aby wstawić znak karetki przed $ HOME, aby to naprawić. Jeśli potrzebujesz, aby Twoje rozwiązanie było idealne, nie używaj tego ...
0fnt
1
@ user18151, niż ty za zwrócenie na to uwagi. Zastąpiłem swoją odpowiedź na ${string/#substring/replacement}wersję, aby temu zapobiec.
Nykakin
1
@ mr.spuratic jest poprawny (oprócz użycia echo) w zsh. W innych powłokach $HOMEbyłby traktowany jako wzór, a całość podlegałaby podziałowi + glob.
Stéphane Chazelas,
Ucieczka od tyldy ('~') załatwiła sprawę. Zauważ, że \ ~ również działa. Jest to wygodne, gdy już znajduje się w '-context: np.PROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"'
Atafar
7
Używanie sed:
pwd | sed "s|^$HOME|~|"
Pomysł polega na użyciu dowolnego znaku, który rzadziej pojawia się w ścieżce katalogu domowego, jako ogranicznika w sedwyrażeniu regularnym. W powyższym przykładzie używam |.
Zaletą tej techniki jest to, że jest ona faktycznie niezależna od powłoki.
Możesz także użyć aliasu, pwdaby /bin/pwd | sed "s|$HOME|~|"uzyskać takie zachowanie w innych skryptach, które mogą być używane pwd.
Musisz dołączyć ^kotwicę do wyrażenia regularnego. W przeciwnym razie jest możliwe (choć mało prawdopodobne) zastąpienie segmentu na środku ścieżki.
Sildoreth,
W rzeczywistości wyrażenie regularne powinno wyglądać następująco "s|^/home/user\(/.*\)\?$|~\1|". W przeciwnym razie jest on zgodny ścieżki inni, jeśli ich nazwy są podobne user1, user2, user3i dopasować tylkouser
AVP
3
tilde=\~${PWD#~}
Myślę, że tego właśnie chcesz?
To, co jest fajne w tyldach, to to, że po rozwinięciu jako wzorzec nie trzeba jej cytować. Używanie $HOMEw ten sam sposób bez cudzysłowów dałoby nieprzewidywalne wyniki, ponieważ każdy z jego znaków składowych może być znakami wzorcowymi, a zatem nie zawsze renderuje oczekiwany wynik.
Jednak specyfikacja tyldy zawsze ma miejsce tak, jakby była wynikiem cytowanej interpretacji, więc jej wyniki są przewidywalne. Wydaje się, że jest to prawdą w praktycznie każdej powłoce, którą testowałem zarówno pod względem casewzorców, jak i wzorców parametrów, z godnymi uwagi wyjątkami zarówno ksh93i mkshz jakichkolwiek powodów - z których żaden nie wydaje się honorować cytowanego aspektu tyldy w tym charakterze.
Kolejną ciekawą rzeczą jest to, że możesz na nowo zdefiniować $HOMEobsługę dowolnego katalogu w ten sam sposób. Na przykład:
cd ~
HOME=/some/prefix/I/would/like/to/trim
#or, perhaps more usefully, some scripted means of arriving at same
tilde=\~${OLDPWD#~}
HOME=$PWD
Oto inny przykład:
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
~
To naprawdę interesujące podejście. Ale zakłada, że $PWDjest poniżej $HOME. Możesz użyć tego samego pomysłu w połączeniu z podstawieniem wzorca, aby uczynić go bardziej ogólnym. Jak się czuje ${PWD/#~/\~}?
Mikel
1
Właściwie odpowiedź Nykakina jest w zasadzie taka.
Mikel
0
Możesz spróbować wymienić niechcianą część na sed:
Musisz użyć ^zakotwiczenia, aby zapewnić zastąpienie tylko dopasowań na początku ścieżki do katalogu. Ponadto nie musisz go używać, gponieważ polecenie powinno zastępować co najwyżej 1 wystąpienie.
Sildoreth,
Dziękuję Ci. Nadal się tego uczę, a wasze komentarze są bardzo pomocne.
user1403360,
Problematyczne, jeśli mój katalog osobisty jest, /home/alicea mój bieżący katalog to /home/aliceinchains. Ale jeśli tylko raz chcę skorzystać z tej funkcji, kiedy wiem, że jestem moim katalogiem domowym lub jednym z jego podkatalogów, powinien on działać.
pwd
. W przeciwnym razie złamiesz skrypty, które oczekują użycia swoich wyników w kontekstach, które nie wykonują interpretacji tyldy.Odpowiedzi:
Jeśli używasz bash, to
dirs
wbudowane ma pożądane zachowanie:(Uwaga
+0
, nie-0
.)Z
zsh
:Aby być dokładnie, najpierw musimy wyczyścić stos katalogów, w przeciwnym
dirs
razie wydrukujemy całą zawartość:Lub z
zsh
„sprint
wbudowanego polecenia:lub
(ten włącza szybkie rozszerzanie .
%~
in$PS1
rozwija się do bieżącego katalogu z$HOME
zastąpionym przez,~
ale obsługuje również inne nazwane katalogi, takie jak katalog domowy innych użytkowników lub nazwane katalogi , które sam definiujesz).źródło
Możesz użyć funkcji zamiany podciągów zmiennych Bash:
źródło
ksh
izsh
.${string/#substring/replacement}
wersję, aby temu zapobiec.echo
) wzsh
. W innych powłokach$HOME
byłby traktowany jako wzór, a całość podlegałaby podziałowi + glob.PROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"'
Używanie
sed
:Pomysł polega na użyciu dowolnego znaku, który rzadziej pojawia się w ścieżce katalogu domowego, jako ogranicznika w
sed
wyrażeniu regularnym. W powyższym przykładzie używam|
.Zaletą tej techniki jest to, że jest ona faktycznie niezależna od powłoki.
Możesz także użyć aliasu,
pwd
aby/bin/pwd | sed "s|$HOME|~|"
uzyskać takie zachowanie w innych skryptach, które mogą być używanepwd
.źródło
^
kotwicę do wyrażenia regularnego. W przeciwnym razie jest możliwe (choć mało prawdopodobne) zastąpienie segmentu na środku ścieżki."s|^/home/user\(/.*\)\?$|~\1|"
. W przeciwnym razie jest on zgodny ścieżki inni, jeśli ich nazwy są podobneuser1
,user2
,user3
i dopasować tylkouser
Myślę, że tego właśnie chcesz?
To, co jest fajne w tyldach, to to, że po rozwinięciu jako wzorzec nie trzeba jej cytować. Używanie
$HOME
w ten sam sposób bez cudzysłowów dałoby nieprzewidywalne wyniki, ponieważ każdy z jego znaków składowych może być znakami wzorcowymi, a zatem nie zawsze renderuje oczekiwany wynik.Jednak specyfikacja tyldy zawsze ma miejsce tak, jakby była wynikiem cytowanej interpretacji, więc jej wyniki są przewidywalne. Wydaje się, że jest to prawdą w praktycznie każdej powłoce, którą testowałem zarówno pod względem
case
wzorców, jak i wzorców parametrów, z godnymi uwagi wyjątkami zarównoksh93
imksh
z jakichkolwiek powodów - z których żaden nie wydaje się honorować cytowanego aspektu tyldy w tym charakterze.Kolejną ciekawą rzeczą jest to, że możesz na nowo zdefiniować
$HOME
obsługę dowolnego katalogu w ten sam sposób. Na przykład:Oto inny przykład:
źródło
$PWD
jest poniżej$HOME
. Możesz użyć tego samego pomysłu w połączeniu z podstawieniem wzorca, aby uczynić go bardziej ogólnym. Jak się czuje${PWD/#~/\~}
?Możesz spróbować wymienić niechcianą część na
sed
:lub nawet lepiej:
źródło
^
zakotwiczenia, aby zapewnić zastąpienie tylko dopasowań na początku ścieżki do katalogu. Ponadto nie musisz go używać,g
ponieważ polecenie powinno zastępować co najwyżej 1 wystąpienie./home/alice
a mój bieżący katalog to/home/aliceinchains
. Ale jeśli tylko raz chcę skorzystać z tej funkcji, kiedy wiem, że jestem moim katalogiem domowym lub jednym z jego podkatalogów, powinien on działać.