鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > 服务器相关 > 批处理 > >

cd 增强版

来源:互联网 作者:佚名 时间:2016-03-17 11:02
zsh 的 cd 有个很吸引我的特性:比如你在 ~/data/foo/horrible/dir/names 目录下,需要切换到 ~/data/bar/horrible/dir/names,只需执行: % pwd~/data/foo/horrible/dir/names% cd foo bar% pwd~/data/bar/horrible/dir/names 我的工作环境是 AIX 5.3,有多

zsh 的 cd 有个很吸引我的特性:比如你在 ~/data/foo/horrible/dir/names 目录下,需要切换到 ~/data/bar/horrible/dir/names,只需执行:

% pwd
~/data/foo/horrible/dir/names
% cd foo bar
% pwd
~/data/bar/horrible/dir/names

我的工作环境是 AIX 5.3,有多套开发环境,经常需要做这样的切换。一开始上面只有最原始的 c shell,因为权限问题,费了很大劲编译出了 bash,zsh 到现在还编不出来,呵呵。所以就自己动手增强一下 cd 命令。增强的功能有:

  1. 诸如 zsh 路径替换的功能;
  2. 支持短名(自动模式匹配),比如要进入 workspace/shell/curl,就输入 cd w/s/c,效果等价于 cd *w*/*s*/*c*。如果有多个路径同时匹配,就将他们全部输出到屏幕;
  3. 简写支持 CDPATH。使用相对路径时,如果当前目录下没找到匹配的路径,就到 CDPATH 下逐一检查。

因为我默认在短命的两头都加上了 *,你可以修改 $i = "*"$i"*" 这一句,改成符合你自己习惯的匹配方式,比如 $i = $i"*",值匹配开头~

cd Bash SHELL 目录 模式
cd () {
  if [ $# -eq 0 ]; then
    command cd
    return $(true)
  elif [ $# -eq 1 ]; then
    if { command cd "$1" 2>/dev/null; }; then
      return $(true)
    fi

    cd_path_pattern=`echo "$1" | awk -F/ -v OFS=/ '{
      for (i = 1; i <= NF; i++) {
        if ($i != "" && $i != "." && $i != ".." && index($i, "*") == 0) {
          $i = "*"$i"*"
        }
      }
      print $0
    }'`

    if [ -z "$cd_path_pattern" ]; then
      unset cd_path_pattern
      return $(false)
    fi
    set $cd_path_pattern

    if [ $# -eq 1 -a "$1" != "$cd_path_pattern" ]; then
      command cd "$1"

      unset cd_path_pattern
      return $(true)
    elif [ $# -gt 1 ]; then
      # ignore file
      cd_path_dir_cnt=`file $cd_path_pattern | sed -n '/: directory/{s///; p}' | wc -l`
      if [ $cd_path_dir_cnt -eq 1 ]; then
        command cd `file $cd_path_pattern | sed -n '/: directory/{s///; p}'`

        unset cd_path_pattern
        unset cd_path_dir_cnt
        return $(true)
      elif [ $cd_path_dir_cnt -gt 1 ]; then
        file $cd_path_pattern | sed -n '/: directory/{s///; p}' >&2

        unset cd_path_pattern
        unset cd_path_dir_cnt
        return $(false)
      fi
    fi

    pattern_with_cd_path=$(echo "$CDPATH" |
      sed 's/:/\n/g' |
      awk -F: '$0 && !a[$0]++' |
      while read pp; do
        pp=`echo "$pp/$cd_path_pattern" | sed "s#/\+#/#g"`
        set $pp
        if [ $# -eq 1 -a "$1" != "$pp" ]; then
          echo "$1" >&1
          break
        elif [ $# -gt 1 ]; then
          cd_path_dir_cnt=`file $pp | sed -n '/: directory/{s///; p}' | wc -l`
          if [ $cd_path_dir_cnt -eq 1 ]; then
            file $pp | sed -n '/: directory/{s///; p}' >&1
            break;
          elif [ $cd_path_dir_cnt -gt 1 ]; then
            file $pp | sed -n '/: directory/{s///; p}' >&2
            break
          fi
        fi
      done)
    if [ ! -z "$pattern_with_cd_path" ]; then
      command cd "$pattern_with_cd_path"
    fi
    unset pattern_with_cd_path
    unset cd_path_pattern
  else
    command cd `pwd | sed "s/$1/$2/g"`
  fi
}
上一篇:Ubuntu PPA Manager
下一篇:没有了
网友评论
<