【问题标题】:Is there a Bash shortcut for traversing similar directory structures?是否有用于遍历类似目录结构的 Bash 快捷方式?
【发布时间】:2010-11-26 01:37:56
【问题描述】:

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 以相同的方式工作?

【问题讨论】:

    标签: bash shell scripting ksh


    【解决方案1】:

    目前提供的其他解决方案存在以下一个或多个问题:

    • 古老的测试形式 - 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

     /canis/lupus/lupus/specimen $ cdX lupus familiaris
        bash: cd: /canis/familiaris/lupus/specimen: 没有这样的文件或目录

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

     /canis/lupus/lupus/specimen $ cd -e lupus familiaris
        /canis/lupus/familiaris/标本 $

    或者从这个发出一个:

     /nicknames/Robert/Rob $ cdX Rob Bob
        bash: cd: /nicknames/Bobert/Rob: 没有这样的文件或目录

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

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

    您也可以像这样明确指定目录:

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

    顺便说一句,我在函数中使用了控制运算符 &&|| 而不是 if...then...else...fi 只是为了品种。

    【讨论】:

      【解决方案2】:
      cd "${PWD/sweet/andy}"
      

      【讨论】:

      • 很抱歉接受然后又把它拿走,但我只好接受丹尼斯的解决方案
      【解决方案3】:

      不,但是……

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

      cd () {
        if [ "x$2" != x ]; then
          builtin cd ${PWD/$1/$2}
        else
          builtin cd "$@"
        fi
      }
      

      【讨论】:

      • 这样更好。谢谢你。我不知道你能做到这一点。我真的必须了解这些新奇的贝壳。当我在 1987 年学习 /bin/sh 时,我使用的东西并不多。看起来 shell 从那时起已经走了很长一段路;-)
      • 嘿,好吧,我确实在脚本中使用了 bashism“内置”。较旧的编写方式是定义“cd”并使用“chdir”来完成实际工作。我不知道我会从巨大的 bash 手册页开始。我认为 ash 和 dash 通常更适合编写脚本,部分原因是文档更易于阅读,部分原因是您可以获得可移植的脚本。您可能想在 Wikipedia 上查找 Ash_shell 和 Debian_Almquist_shell,也许可以查看:netbsd.gw.com/cgi-bin/man-cgi?sh++NetBSD-current
      • 但是伙计,这是 bash。即使是 POSIX shell 也不需要这么难看的测试;普通的 [[ "$2" ]] 要好得多。
      猜你喜欢
      • 2010-11-23
      • 1970-01-01
      • 2011-06-22
      • 2017-07-04
      • 2011-03-10
      • 1970-01-01
      • 1970-01-01
      • 2010-09-25
      • 2010-11-03
      相关资源
      最近更新 更多