Si vous allez faire cela, je vous recommande fortement de nommer la commande résultante autrement que pwd. Sinon, vous casserez les scripts qui s'attendent à utiliser sa sortie dans des contextes qui n'effectuent pas l'expansion de tilde.
Charles Duffy
Réponses:
25
Si vous utilisez bash, le programme dirsintégré a le comportement souhaité:
Pour être exact, nous devons d'abord vider la pile des répertoires, sinon dirs, tout le contenu serait affiché:
dirs -c; dirs
Ou avec zshde » printl'builtin:
print -rD $PWD
ou
print -P %~
(que l' on tourne l' expansion rapide sur. %~en se $PS1détend dans le répertoire courant avec $HOMEremplacé par , ~mais gère également d' autres répertoires nommés comme le répertoire d'autres utilisateurs ou répertoires nommés que vous définiriez).
Je change tout le temps entre bash et zsh. Malheureusement, cette solution m'oblige à me souvenir de la différence entre les obus et aussi à me souvenir (de vérifier) où je suis actuellement. La réponse de @Bichoy est indépendante de l'environnement pour ces deux-là.
avp
18
Vous pouvez utiliser la fonction de remplacement de sous-chaîne variable Bash:
Bien que j'aie voté pour cette réponse parce que c'est la manière la plus simple, il y a une petite mise en garde ici: à l'intérieur de / tmp / home / username, cela renverra / tmp ~. Je ne trouve pas de moyen d'insérer un signe d'insertion avant $ HOME pour résoudre ce problème. Si vous avez besoin que votre solution soit parfaite, ne l'utilisez pas ...
0fnt
1
@ user18151, que vous pour l'avoir signalé. J'ai remplacé ma réponse à la ${string/#substring/replacement}version pour éviter ce problème.
Nykakin
1
@ mr.spuratic c'est juste correct (sauf pour l'utilisation de echo) dans zsh. Dans d'autres coquilles, $HOMEserait traité comme un motif et le tout soumis à split + glob.
Stéphane Chazelas
Échapper au tilde ('~') a fait l'affaire. Notez que \ ~ fonctionne également. C'est pratique quand vous êtes déjà dans '-context: par exemple,PROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"'
Atafar
7
En utilisant sed:
pwd | sed "s|^$HOME|~|"
L'idée est d'utiliser n'importe quel caractère qui est moins susceptible d'apparaître dans un chemin de répertoire personnel comme délimiteur dans l' sedexpression régulière. Dans l'exemple ci-dessus, j'utilise |.
La bonne chose à propos de cette technique est qu'elle est en fait indépendante du shell.
Vous pouvez également créer un alias pwdpour /bin/pwd | sed "s|$HOME|~|"obtenir ce comportement dans d'autres scripts qui pourraient être utilisés pwd.
Vous devez inclure l' ^ancre dans votre expression régulière. Sinon, il est possible (mais peu probable) de remplacer un segment au milieu du chemin.
Sildoreth
En fait, l'expression régulière doit ressembler à ceci "s|^/home/user\(/.*\)\?$|~\1|". Sinon , il correspond à d' autres chemins des utilisateurs si leurs noms sont comme user1, user2, user3et vous devez faire correspondreuser
AVP
3
tilde=\~${PWD#~}
Je pense que c'est ce que tu veux?
Ce qui est bien avec le tilde, c'est quand il est développé en tant que modèle, il n'a pas besoin d'être cité. L'utilisation $HOMEde la même manière sans guillemets rendrait des résultats imprévisibles car l'un de ses caractères constitutifs pourrait être des caractères de motif, et donc il pourrait ne pas toujours rendre le résultat attendu.
Mais l'expansion tilde est censée se produire toujours comme si elle était le résultat d'une expansion citée, et donc ses résultats sont prévisibles. Cela semble vrai dans pratiquement tous les shell que j'ai testés pour les casemodèles et les modèles de paramètres, à l'exception notable des deux ksh93et mkshpour quelque raison que ce soit - ni l'un ni l'autre ne semble honorer l'aspect cité du tilde à ce titre.
Une autre chose intéressante à ce sujet est que vous pouvez redéfinir $HOMEpour gérer n'importe quel répertoire du tout de la même manière. Par exemple:
cd ~
HOME=/some/prefix/I/would/like/to/trim
#or, perhaps more usefully, some scripted means of arriving at same
tilde=\~${OLDPWD#~}
HOME=$PWD
Voici un autre exemple:
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
~
C'est une approche vraiment intéressante. Mais il suppose que $PWDc'est en dessous $HOME. Vous pouvez utiliser la même idée combinée à la substitution de motifs pour la rendre plus générale. Comment va ${PWD/#~/\~}?
Mikel
1
En fait, la réponse de Nykakin est essentiellement cela.
Mikel
0
Vous pouvez essayer de remplacer la partie indésirable par sed:
Vous devez utiliser l' ^ancre pour vous assurer que seules les correspondances au début du chemin du répertoire sont remplacées. De plus, vous n'avez pas besoin de l'utiliser gcar la commande doit remplacer au maximum 1 occurrence.
Sildoreth
Merci. J'apprends encore ces choses et votre commentaire est vraiment utile.
user1403360
Problématique si mon répertoire personnel est /home/aliceet mon répertoire actuel l'est /home/aliceinchains. Mais si la seule fois où je veux utiliser cette fonctionnalité, c'est quand je sais que je suis mon répertoire personnel ou l'un de ses sous-répertoires, cela devrait fonctionner.
pwd
. Sinon, vous casserez les scripts qui s'attendent à utiliser sa sortie dans des contextes qui n'effectuent pas l'expansion de tilde.Réponses:
Si vous utilisez bash, le programme
dirs
intégré a le comportement souhaité:(Remarque
+0
, non-0
.)Avec
zsh
:Pour être exact, nous devons d'abord vider la pile des répertoires, sinon
dirs
, tout le contenu serait affiché:Ou avec
zsh
de »print
l'builtin:ou
(que l' on tourne l' expansion rapide sur.
%~
en se$PS1
détend dans le répertoire courant avec$HOME
remplacé par ,~
mais gère également d' autres répertoires nommés comme le répertoire d'autres utilisateurs ou répertoires nommés que vous définiriez).la source
Vous pouvez utiliser la fonction de remplacement de sous-chaîne variable Bash:
la source
ksh
etzsh
.${string/#substring/replacement}
version pour éviter ce problème.echo
) danszsh
. Dans d'autres coquilles,$HOME
serait traité comme un motif et le tout soumis à split + glob.PROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"'
En utilisant
sed
:L'idée est d'utiliser n'importe quel caractère qui est moins susceptible d'apparaître dans un chemin de répertoire personnel comme délimiteur dans l'
sed
expression régulière. Dans l'exemple ci-dessus, j'utilise|
.La bonne chose à propos de cette technique est qu'elle est en fait indépendante du shell.
Vous pouvez également créer un alias
pwd
pour/bin/pwd | sed "s|$HOME|~|"
obtenir ce comportement dans d'autres scripts qui pourraient être utiliséspwd
.la source
^
ancre dans votre expression régulière. Sinon, il est possible (mais peu probable) de remplacer un segment au milieu du chemin."s|^/home/user\(/.*\)\?$|~\1|"
. Sinon , il correspond à d' autres chemins des utilisateurs si leurs noms sont commeuser1
,user2
,user3
et vous devez faire correspondreuser
Je pense que c'est ce que tu veux?
Ce qui est bien avec le tilde, c'est quand il est développé en tant que modèle, il n'a pas besoin d'être cité. L'utilisation
$HOME
de la même manière sans guillemets rendrait des résultats imprévisibles car l'un de ses caractères constitutifs pourrait être des caractères de motif, et donc il pourrait ne pas toujours rendre le résultat attendu.Mais l'expansion tilde est censée se produire toujours comme si elle était le résultat d'une expansion citée, et donc ses résultats sont prévisibles. Cela semble vrai dans pratiquement tous les shell que j'ai testés pour les
case
modèles et les modèles de paramètres, à l'exception notable des deuxksh93
etmksh
pour quelque raison que ce soit - ni l'un ni l'autre ne semble honorer l'aspect cité du tilde à ce titre.Une autre chose intéressante à ce sujet est que vous pouvez redéfinir
$HOME
pour gérer n'importe quel répertoire du tout de la même manière. Par exemple:Voici un autre exemple:
la source
$PWD
c'est en dessous$HOME
. Vous pouvez utiliser la même idée combinée à la substitution de motifs pour la rendre plus générale. Comment va${PWD/#~/\~}
?Vous pouvez essayer de remplacer la partie indésirable par
sed
:ou encore mieux:
la source
^
ancre pour vous assurer que seules les correspondances au début du chemin du répertoire sont remplacées. De plus, vous n'avez pas besoin de l'utiliserg
car la commande doit remplacer au maximum 1 occurrence./home/alice
et mon répertoire actuel l'est/home/aliceinchains
. Mais si la seule fois où je veux utiliser cette fonctionnalité, c'est quand je sais que je suis mon répertoire personnel ou l'un de ses sous-répertoires, cela devrait fonctionner.