使pwd结果用“〜”表示吗?


28

pwd 给我

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

有没有一种简单的方法来获取

~/some/random/folder

来自pwd


是否可以通过sed进行配管?
马修·斯科尔菲尔德

7
如果您要执行此操作,强烈建议您将结果命令命名为pwd。否则,您将破坏期望在不执行波浪号扩展的上下文中使用其输出的脚本。
Charles Duffy

Answers:


25

如果您使用的是bash,则dirs内置函数具有所需的行为:

dirs +0
~/some/random/folder

(注意+0,不是-0。)

zsh

dirs
~/some/random/folder

确切地说,我们首先需要清除目录堆栈,否则dirs将打印所有内容:

dirs -c; dirs

或者用zshprint内置:

print -rD $PWD

要么

print -P %~

(即一个打开提示扩张上,%~$PS1扩展到与当前目录$HOME替换为~也处理其他命名的目录像其他用户或主目录命名的目录,你自己定义)。


我一直在bash和zsh之间切换。不幸的是,这种解决方案迫使我记住外壳之间的差异,并记住(检查)我当前所在的位置。@Bichoy的答案对于这两个来说是不可知的。
AVP

18

您可以使用Bash变量子字符串替换功能:

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

2
这也适用于kshzsh
6

1
尽管我以最简单的方式赞成这个答案,但这里有一个小警告:/ tmp / home / username内,它将返回/ tmp〜。我找不到在$ HOME之前插入插入符号的方法来解决此问题。如果您需要完美的解决方案,请不要使用它...
0fnt 2015年

1
@ user18151,而不是您指出这一点。我替换了对${string/#substring/replacement}版本的回答,以防止出现这种情况。
Nykakin 2015年

1
@ mr.spuratic仅在中是正确的(使用除外echozsh。在其他shell中,$HOME将其视为模式,整个对象将受到split + glob的影响。
斯特凡Chazelas

转义波浪符号('〜')可以解决问题。注意\〜也可以。当已经处于'-context中时,这很方便:例如,PROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"'
Atafar

7

使用sed

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

这个想法是使用不太可能出现在主目录路径中的任何字符作为sed正则表达式中的分隔符。在上面的示例中,我使用|

这项技术的好处是它实际上与外壳无关。

您也可以别名pwd,以/bin/pwd | sed "s|$HOME|~|"获得在其他脚本这种行为可能被使用pwd


2
您需要^在正则表达式中包含锚。否则,有可能(但是不太可能)替换路径中间的线段。
Sildoreth

实际上,正则表达式应如下所示"s|^/home/user\(/.*\)\?$|~\1|"。否则,如果其他用户的名称类似于user1,,则它与其他用户的路径匹配user2user3而您只匹配user
avp

3
tilde=\~${PWD#~}

我想那就是你想要的?

波浪号的整洁之处在于将波浪号扩展为不需要引用的模式时。以$HOME相同的方式使用不带引号的结果将导致不可预测的结果,因为其任何构成字符都可能是模式字符,因此它可能并不总是呈现预期的结果。

但是,代字号扩展通常总是好像是引号扩展的结果一样发生,因此其结果是可预测的。在我测试过的case模式和参数模式的几乎所有外壳程序中,似乎都是如此ksh93mksh但无论是哪种原因,无论出于什么原因,都存在明显的例外-两者似乎都不以这种能力来认可波浪号的引用方面。

与此相关的另一件事是,您可以重新定义$HOME以完全相同的方式处理任何目录。例如:

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

这是另一个例子:

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
这是一个非常有趣的方法。但它假设$PWD在之下$HOME。您可以将相同的想法与模式替换结合使用,以使其更通用。怎么${PWD/#~/\~}
Mikel 2015年

1
实际上,尼卡金的答案基本上就是这样。
Mikel 2015年

0

您可以尝试将不需要的部分替换为sed

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

甚至更好:

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

1
您需要使用^锚来确保仅替换目录路径开头的匹配项。另外,您不需要使用g该命令,因为该命令最多应替换1个事件。
Sildoreth

谢谢。我仍然在学习这些东西,您的评论真的很有帮助。
user1403360 2015年

如果我的主目录是,/home/alice而我的当前目录是,则有问题/home/aliceinchains。但是,如果我唯一想使用该功能的时间是当我知道自己是主目录或其子目录之一时,它应该可以工作。
Mihai Danila
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.