如何使用最近的三个文件夹设置提示../c/Users/test
How to setup prompt with three nearest folders ../c/Users/test
这是一个示例:../c/Users/test
我仍然不知道如何实现此 zsh 的提示,如果可能的话,它在 bash
?
中的表现如何
编辑:nearest
意味着我的 pwd
将显示为即:/home/abc/c/Users/test
。
如果我在/home/abc/c
或/home/abc
或/home
下,提示应该是/home/abc/c>
或/home/abc>
或/home>
因此只有超过三个文件夹的当前路径才会在前面附加 ..
和三个 nearest
文件夹。
这似乎可以解决问题:
PS1='$(pwd|sed -r "sx.+(/[^/]*/[^/]*/[^/]*)$x..x" ):'
例如:
jasen@gonzo:/var/spool/news/comp/lang/c/moderated$ PS1='$(pwd|sed -r "sx.+(/[^/]*/[^/]*/[^/]*)$x..x" ):'
../lang/c/moderated:cd
/home/jasen:
工作原理:
PS1
展开以产生提示。
我使用命令替换 $(
... )
将命令的输出插入到提示中。
命令本身就是一个管道
首先pwd
显示当前目录
它的输出在扩展 (-r
) 正则表达式模式下通过管道 (|
) 传输到 sed
。 sed 给出了命令。
"sx.+(/[^/]*/[^/]*/[^/]*)$x..x"
这是一个 s
替换命令
在这个命令中,s后面的符号是我在这里使用的分隔符x
短语 [^/]*
表示零个或多个非斜杠的序列(如目录名称),而其他斜杠 /
表示实际斜杠, .+
匹配任何内容(但不匹配没有什么)。 $
表示行尾。
所以从美元开始,它匹配以 /name/name/name
结尾的行
第二个 X 之后的位 ..
是用来替换匹配项的内容。在这种情况下 ..
后跟包含在与括号模式匹配的位中的位。 ../name/name/name
ZSH
在 zsh
中,这完全可以通过内置功能实现。你只需要放置
%(4/|../%3d|%d)
在您的 PROMPT
参数中(也称为 PS1
)。
例如:
PROMPT='[%m@%n %(4/|../%3d|%d)]%# '
会给你类似的东西
[abc@machine ../c/Users/test]%
当当前目录为/home/abc/c/Users/test
.
解释:
%(x|true-text|false-text)
: x
代表一个测试,如果它评估为 true 它 zsh
将打印放置的内容为 true-text 否则它将打印 false-text。
如果当前绝对路径至少有 4 个元素,4/
为 true。例如 /home/abc/c/Users/test
有 5 个元素
- 因此,如果当前路径有 4 个或更多元素,则输出为
../%3d
,其中 %3d
将替换为当前路径的最后 3 个元素。例如 ../c/Users/test
.
- 如果当前路径少于 4 个元素,则输出
%d
,将被完整的当前路径替换。
BASH
方法一:简单但不完美
在bash
(自版本 4 起)中,您可以通过设置 PROMPT_DIRTRIM=3
并在 PS1
中放置 \w
来获得非常相似的结果。这也将只显示当前路径的最后 3 个元素,前面是 ~/.../
或 .../
。这取决于当前目录是否在用户的主目录中。
例如:
PS1='[\u@\h \w]$ '
PROMPT_DIRTRIM=3
会得到你
[abc@machine ~/.../c/Users/test]$
当当前工作目录为 /home/abc/c/Users/test
和
时
[abc@machine .../share/doc/sometool]$
当当前工作目录是 /usr/local/share/doc/sometool
.
方法二:复杂但按要求行得通
要完全匹配,请在 PS1
中放置以下内容:
$(a=${PWD%/*} a=${a%/*} a=${a%/*}; echo ${PWD/#$a/${a:+..}})
例如
PS1='[\u@\h $(a=${PWD%/*} a=${a%/*} a=${a%/*}; echo ${PWD/#$a/${a:+..}})]$ '
重要提示:至少生成路径输出的部分需要完整引用,例如被单引号包围。否则它将在定义时计算,而不是在显示提示时计算。
解释:
$(command)
:这称为命令替换。它将 运行 command
然后替换为结果输出。
- 参数
PWD
包含当前工作目录。
a=${PWD%/*}
:/*
的最短可能匹配将从 $PWD
的末尾删除,结果值将分配给参数 a
。也就是说,最后一个路径元素将从 $PWD
. 中删除
a=${PWD%/*} a=${a%/*} a=${a%/*}
:这会从 $PWD
中删除最后三个路径元素。如果 $PWD
有三个或更少的元素,那么 a
将在末尾为空。如果元素多于三个,则 a
包含您不想显示的所有元素,即您想要替换为 ..
的元素。
(注意:虽然 a=${PWD%/*/*/*}
也删除了最后三个路径元素,但如果元素少于三个,它不会按预期工作。在那种情况下$PWD
的末尾与 /*/*/*
不匹配,不会删除任何内容,留下 $a
与 $PWD
相同。)
${a:+..}
:如果定义了 a
且不为空,则将由 ..
替换,否则不替换任何内容。这意味着如果有要删除的路径元素,则 ${a:+..}
将计算为 ..
.
${PWD/#$a/${a:+..}})
:如果$PWD
的开头匹配$a
,那么它会被${a:+..}
替换。本质上,如果 a
包含任何路径元素,那么它们将被 ..
替换,否则什么都不会改变。
echo
:由于这一切都发生在命令替换中,因此需要echo
才能输出缩短的路径。
这是一个示例:../c/Users/test
我仍然不知道如何实现此 zsh 的提示,如果可能的话,它在 bash
?
编辑:nearest
意味着我的 pwd
将显示为即:/home/abc/c/Users/test
。
如果我在/home/abc/c
或/home/abc
或/home
下,提示应该是/home/abc/c>
或/home/abc>
或/home>
因此只有超过三个文件夹的当前路径才会在前面附加 ..
和三个 nearest
文件夹。
这似乎可以解决问题:
PS1='$(pwd|sed -r "sx.+(/[^/]*/[^/]*/[^/]*)$x..x" ):'
例如:
jasen@gonzo:/var/spool/news/comp/lang/c/moderated$ PS1='$(pwd|sed -r "sx.+(/[^/]*/[^/]*/[^/]*)$x..x" ):'
../lang/c/moderated:cd
/home/jasen:
工作原理:
PS1
展开以产生提示。
我使用命令替换 $(
... )
将命令的输出插入到提示中。
命令本身就是一个管道
首先pwd
显示当前目录
它的输出在扩展 (-r
) 正则表达式模式下通过管道 (|
) 传输到 sed
。 sed 给出了命令。
"sx.+(/[^/]*/[^/]*/[^/]*)$x..x"
这是一个 s
替换命令
在这个命令中,s后面的符号是我在这里使用的分隔符x
短语 [^/]*
表示零个或多个非斜杠的序列(如目录名称),而其他斜杠 /
表示实际斜杠, .+
匹配任何内容(但不匹配没有什么)。 $
表示行尾。
所以从美元开始,它匹配以 /name/name/name
第二个 X 之后的位 ..
是用来替换匹配项的内容。在这种情况下 ..
后跟包含在与括号模式匹配的位中的位。 ../name/name/name
ZSH
在 zsh
中,这完全可以通过内置功能实现。你只需要放置
%(4/|../%3d|%d)
在您的 PROMPT
参数中(也称为 PS1
)。
例如:
PROMPT='[%m@%n %(4/|../%3d|%d)]%# '
会给你类似的东西
[abc@machine ../c/Users/test]%
当当前目录为/home/abc/c/Users/test
.
解释:
%(x|true-text|false-text)
:x
代表一个测试,如果它评估为 true 它zsh
将打印放置的内容为 true-text 否则它将打印 false-text。
如果当前绝对路径至少有 4 个元素,4/
为 true。例如/home/abc/c/Users/test
有 5 个元素- 因此,如果当前路径有 4 个或更多元素,则输出为
../%3d
,其中%3d
将替换为当前路径的最后 3 个元素。例如../c/Users/test
. - 如果当前路径少于 4 个元素,则输出
%d
,将被完整的当前路径替换。
BASH
方法一:简单但不完美
在bash
(自版本 4 起)中,您可以通过设置 PROMPT_DIRTRIM=3
并在 PS1
中放置 \w
来获得非常相似的结果。这也将只显示当前路径的最后 3 个元素,前面是 ~/.../
或 .../
。这取决于当前目录是否在用户的主目录中。
例如:
PS1='[\u@\h \w]$ '
PROMPT_DIRTRIM=3
会得到你
[abc@machine ~/.../c/Users/test]$
当当前工作目录为 /home/abc/c/Users/test
和
[abc@machine .../share/doc/sometool]$
当当前工作目录是 /usr/local/share/doc/sometool
.
方法二:复杂但按要求行得通
要完全匹配,请在 PS1
中放置以下内容:
$(a=${PWD%/*} a=${a%/*} a=${a%/*}; echo ${PWD/#$a/${a:+..}})
例如
PS1='[\u@\h $(a=${PWD%/*} a=${a%/*} a=${a%/*}; echo ${PWD/#$a/${a:+..}})]$ '
重要提示:至少生成路径输出的部分需要完整引用,例如被单引号包围。否则它将在定义时计算,而不是在显示提示时计算。
解释:
$(command)
:这称为命令替换。它将 运行command
然后替换为结果输出。- 参数
PWD
包含当前工作目录。 a=${PWD%/*}
:/*
的最短可能匹配将从$PWD
的末尾删除,结果值将分配给参数a
。也就是说,最后一个路径元素将从$PWD
. 中删除
a=${PWD%/*} a=${a%/*} a=${a%/*}
:这会从$PWD
中删除最后三个路径元素。如果$PWD
有三个或更少的元素,那么a
将在末尾为空。如果元素多于三个,则a
包含您不想显示的所有元素,即您想要替换为..
的元素。(注意:虽然
a=${PWD%/*/*/*}
也删除了最后三个路径元素,但如果元素少于三个,它不会按预期工作。在那种情况下$PWD
的末尾与/*/*/*
不匹配,不会删除任何内容,留下$a
与$PWD
相同。)${a:+..}
:如果定义了a
且不为空,则将由..
替换,否则不替换任何内容。这意味着如果有要删除的路径元素,则${a:+..}
将计算为..
.${PWD/#$a/${a:+..}})
:如果$PWD
的开头匹配$a
,那么它会被${a:+..}
替换。本质上,如果a
包含任何路径元素,那么它们将被..
替换,否则什么都不会改变。echo
:由于这一切都发生在命令替换中,因此需要echo
才能输出缩短的路径。