5

KornShell (ksh) 曾经有一个非常有用的选项来cd遍历类似的目录结构;例如,给定以下目录:

  • /home/sweet/dev/projects/trunk/projecta/app/models
  • /home/andy/dev/projects/trunk/projecta/app/models

然后,如果您在/home/sweet...目录中,则可以通过键入更改到 andy 结构中的等效目录

cd sweet andy

因此,如果 ksh 看到 2 个参数,那么它将扫描当前目录路径以查找第一个值,将其替换为第二个值并 cd 在那里。有人知道 Bash 内置了类似的功能吗?或者,如果没有,让 Bash 以同样的方式工作的技巧?

4

3 回答 3

5

迄今为止提供的其他解决方案存在以下一个或多个问题:

  • 古老的测试形式——正如Michał Górny所指出的
  • 对包含空格的目录名称的不完全保护
  • 无法处理多次使用相同名称或具有匹配的子字符串的目录结构:/canis/lupus/lupus//nicknames/Robert/Rob/

这个版本处理了上面列出的所有问题。

cd () 
{ 
    local pwd="${PWD}/"; # we need a slash at the end so we can check for it, too
    if [[ "$1" == "-e" ]]
    then
        shift
        # start from the end
        [[ "$2" ]] && builtin cd "${pwd%/$1/*}/${2:-$1}/${pwd##*/$1/}" || builtin cd "$@"
    else
        # start from the beginning
        [[ "$2" ]] &&  builtin cd "${pwd/\/$1\///$2/}" || builtin cd "$@"
    fi
}

从如下目录发布任何其他版本,我将调用cdX它:

    /犬/狼疮/狼疮/标本 $ cdX 狼疮熟悉
    bash: cd: /canis/familiaris/lupus/specimen: 没有这样的文件或目录

如果“狼疮”的第二个实例是预期的,则失败。为了适应这种情况,您可以使用“ -e”选项目录结构的末尾开始。

    /犬/狼疮/狼疮/标本 $ cd -e 狼疮熟悉
    /犬/狼疮/家庭/标本 $

或者从这个发行其中之一:

    /昵称/罗伯特/Rob $ cdX Rob Bob
    bash: cd: /nicknames/Bobert/Rob: 没有这样的文件或目录

会无意中替换字符串的一部分。我的函数通过在匹配中包含斜线来处理这个问题。

    /昵称/罗伯特/Rob $ cd Rob Bob
    /昵称/罗伯特/鲍勃 $

你也可以像这样明确地指定一个目录:

    /fish/fish/fins $ cd 鱼/鳍 机器人/鳍
    /鱼/机器人/鳍 $

顺便说一句,我在我的函数中使用了控制运算符而不是…………&&只是为了多样化。||ifthenelsefi

于 2009-09-07T05:44:49.450 回答
3
cd "${PWD/sweet/andy}"
于 2009-09-06T19:43:57.270 回答
2

不是,但...

Michał Górny 的替换表达式效果很好。要重新定义内置 cd 命令,请执行以下操作:

cd () {
  if [ "x$2" != x ]; then
    builtin cd ${PWD/$1/$2}
  else
    builtin cd "$@"
  fi
}
于 2009-09-06T19:40:25.407 回答