我在 Magento 中做了很多工作,很多与我一起工作的人也是如此,而且必须输入以下内容会很烦人:
光盘 ../../../../../../
为了只发现距根“httpdocs”文件夹还有几个目录,所以我尝试制作一个遵循以下伪代码的脚本:
while lowest level directory != httpdocs
cd ../
end while;
看起来很简单,我假设我必须执行某种形式的 grep 来检查当前工作目录的最后一部分是否为 httpdocs,如果不是,则继续上一级直到它为真。
我一直在考虑为此学习 bash,尽管似乎已经有类似的东西了,而且语法让我困惑不已。
答案1
我在 .bashrc 中调用了一个函数upto
,它允许您按名称进入当前路径上的任何目录:
upto ()
{
if [ -z "$1" ]; then
return
fi
local upto=$1
cd "${PWD/\/$upto\/*//$upto}"
}
我还完成了这个函数,这样当我点击选项卡时它就会给我有效的目录名称和完成:
_upto()
{
local cur=${COMP_WORDS[COMP_CWORD]}
local d=${PWD//\//\ }
COMPREPLY=( $( compgen -W "$d" -- "$cur" ) )
}
complete -F _upto upto
此外,我还有另一个功能jd
,可以让我跳转到当前目录下的任何目录:
jd(){
if [ -z "$1" ]; then
echo "Usage: jd [directory]";
return 1
else
cd **"/$1"
fi
}
例子:
[/www/public_html/animals/hippopotamus/habitat/swamps/images] $ upto h[TAB][TAB]
habitat hippopotamus
[/www/public_html/animals/hippopotamus/habitat/swamps/images] $ upto hippopotamus
[/www/public_html/animals/hippopotamus] $ jd images
[/www/public_html/animals/hippopotamus/habitat/swamps/images] $
答案2
这必须是一个外壳函数,而不是脚本,因为脚本在新 shell 中执行(因此无法更改原始 shell 的目录)。
function cdroot()
{
while [[ $PWD != '/' && ${PWD##*/} != 'httpdocs' ]]; do cd ..; done
}
当然,您可以随意命名该函数。
一些解释:第一个测试 ( $PWD != '/'
) 是一个故障保护,以防万一您cdroot
不在 httpdocs 文件夹内时进行测试。当你到达根部时它就会停止。
第二个测试 ( ${PWD##*/} != 'httpdocs'
) 有点复杂。 $PWD
是一个包含当前目录路径的变量。${PWD##*/}
修剪所有内容直到并包括最后一个斜杠。
答案3
我能想到的最简单的 bash 函数.bashrc
(简单是因为它不使用循环或外部进程)是:
cdup() {
cd "${PWD/\/httpdocs\/*//httpdocs}"
}
这使用了模式替换/httpdocs/
参数扩展将in后面的所有内容替换$PWD
为“/httpdocs”。它看起来非常混乱,因为我们必须转义路径中的正斜杠,以将它们与 bash 扩展语法中的正斜杠区分开来。另外,不要在替换字符串中转义正斜杠,因此它看起来也不一致。
如果当前路径中没有,/httpdocs/
则不会执行任何替换,只会更改为当前目录。
例如,替换将替换/a/b/c/httpdocs/e/f/g
为/a/b/c/httpdocs
并cd
进入该目录。
该函数需要位于当前的 shell 环境中(作为函数或别名),因为子进程无法更改其父进程的当前目录。这就是为什么我说把它放在你的脚本中.bashrc
而不是放在 shell 脚本中。