Rendere il risultato pwd in termini di "~"?


28

pwd mi da

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

C'è un modo semplice per ottenere

~/some/random/folder

da pwd?


Il piping attraverso sed è un'opzione?
Matthew D. Scholefield,

7
Se hai intenzione di farlo, ti consiglio vivamente di nominare il comando risultante in modo diverso pwd. Altrimenti, interromperai gli script che prevedono di utilizzare il suo output in contesti che non eseguono l'espansione della tilde.
Charles Duffy,

Risposte:


25

Se stai usando bash, l' dirsintegrato ha il comportamento desiderato:

dirs +0
~/some/random/folder

(Nota +0, no-0 .)

Con zsh:

dirs
~/some/random/folder

Per essere precisi, dobbiamo prima cancellare lo stack di directory, altrimenti dirsstampare tutti i contenuti:

dirs -c; dirs

O con zsh's printincorporato:

print -rD $PWD

o

print -P %~

(che ci si rivolge pronta espansione su. %~nel $PS1espande nella directory corrente con $HOMEsostituite con ~, ma gestisce anche altri directory denominate come la home directory di altri utenti o nome directory che si definiscono da soli).


Passo sempre tra bash e zsh. Sfortunatamente questa soluzione mi costringe a ricordare la differenza tra le conchiglie e anche a ricordare (per verificare) dove mi trovo attualmente. La risposta di @Bichoy è agnostica per questi due.
avp,

18

È possibile utilizzare la funzione di sostituzione della sottostringa variabile di Bash:

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

2
Questo funziona anche in kshe zsh.
mr.spuratic,

1
Mentre ho votato questa risposta perché è il modo più semplice, qui c'è un piccolo avvertimento: dentro / tmp / home / username, questo restituirà / tmp ~. Non riesco a trovare un modo per inserire un segno di cursore prima di $ HOME per risolvere il problema. Se hai bisogno che la tua soluzione sia perfetta, non usare questo ...
0fnt

1
@ user18151, di te per averlo segnalato. Ho sostituito la mia risposta alla ${string/#substring/replacement}versione per evitare questo comportamento.
Nykakin,

1
@ mr.spuratic è corretto (tranne per l'uso di echo) in zsh. In altre conchiglie, $HOMEverrebbe trattato come un modello e il tutto soggetto a split + glob.
Stéphane Chazelas,

Escaping the tilde ('~') ha funzionato. Nota che \ ~ funziona anche. È utile quando si è già nel '-contesto: ad es.PROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"'
Atafar

7

Utilizzando sed:

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

L'idea è di utilizzare qualsiasi carattere che ha meno probabilità di apparire in un percorso della directory home come delimitatore in sedregex. Nell'esempio sopra sto usando |.

La cosa buona di questa tecnica è che in realtà è indipendente dalla shell.

Puoi anche alias pwdper /bin/pwd | sed "s|$HOME|~|"ottenere questo comportamento in altri script che potrebbero essere in uso pwd.


2
Devi includere l' ^ancoraggio nella tua regex. Altrimenti, è possibile (per quanto improbabile) che questo sostituisca un segmento nel mezzo del percorso.
Sildoreth,

In realtà il regex dovrebbe apparire come segue "s|^/home/user\(/.*\)\?$|~\1|". In caso contrario, corrisponde percorsi di altri utenti se i loro nomi sono come user1, user2, user3e si abbinano solouser
UdP

3
tilde=\~${PWD#~}

Penso che sia quello che vuoi?

La cosa bella della tilde è quando viene espansa come un modello che non ha bisogno di essere citato. Usare $HOMEallo stesso modo senza virgolette renderebbe risultati imprevedibili perché uno qualsiasi dei suoi caratteri costituenti potrebbe essere un modello, e quindi potrebbe non rendere sempre il risultato previsto.

Ma si prevede che l'espansione della tilde si verifichi sempre come se fosse il risultato di un'espansione quotata, e quindi i suoi risultati sono prevedibili. Questo sembra valere praticamente in ogni shell che ho testato sia per i casemodelli che per i parametri con le notevoli eccezioni di entrambi ksh93e mkshper qualsiasi motivo - nessuno dei quali sembra onorare l'aspetto citato della tilde in quella veste.

Un'altra cosa interessante di questo è che puoi ridefinire $HOMEper gestire qualsiasi directory allo stesso modo. Per esempio:

cd ~
HOME=/some/prefix/I/would/like/to/trim 
#or, perhaps more usefully, some scripted means of arriving at same
tilde=\~${OLDPWD#~}
HOME=$PWD

Ecco un altro esempio:

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
Questo è un approccio davvero interessante. Ma presume che $PWDsia sotto $HOME. Potresti usare la stessa idea combinata con la sostituzione del modello per renderla più generale. Come va ${PWD/#~/\~}?
Mikel,

1
In realtà la risposta di Nykakin è sostanzialmente questa.
Mikel,

0

Puoi provare a sostituire la parte indesiderata con sed:

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

o anche meglio:

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

1
È necessario utilizzare l' ^ancoraggio per assicurarsi che vengano sostituite solo le corrispondenze all'inizio del percorso della directory. Inoltre, non è necessario utilizzarlo gperché il comando dovrebbe sostituire al massimo 1 occorrenza.
Sildoreth,

Grazie. Sto ancora imparando queste cose e il tuo commento è davvero utile.
user1403360

Problematico se la mia directory home è /home/alicee la mia directory corrente è /home/aliceinchains. Ma se l'unica volta che voglio usare la funzione è quando so che sono la mia directory home o una delle sue sottodirectory, allora dovrebbe funzionare.
Mihai Danila,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.