cd 增强版
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 命令。增强的功能有:
- 诸如 zsh 路径替换的功能;
- 支持短名(自动模式匹配),比如要进入 workspace/shell/curl,就输入 cd w/s/c,效果等价于 cd *w*/*s*/*c*。如果有多个路径同时匹配,就将他们全部输出到屏幕;
- 简写支持 CDPATH。使用相对路径时,如果当前目录下没找到匹配的路径,就到 CDPATH 下逐一检查。
因为我默认在短命的两头都加上了 *,你可以修改 $i = "*"$i"*" 这一句,改成符合你自己习惯的匹配方式,比如 $i = $i"*",值匹配开头~
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 }
返回多层父目录
另外,还有一个方便的返回上层目录的函数配合使用:
.. () { if [ $# -eq 0 ] || [ $1 -le 0 ]; then cd_parent_cnt=1 else cd_parent_cnt=$1 fi while [ $cd_parent_cnt -gt 0 ] && [ "$PWD" != "/" ]; do command cd .. cd_parent_cnt=`expr $cd_parent_cnt - 1` done unset cd_parent_cnt }
有些朋友定义了一个别名 alias ..='cd ..',不过在返回多层目录时感觉并没有方便多少。用上面的函数,如果要返回上 5 层,就执行 .. 5 即可。
版权声明
为方便其他朋友提问和指正,转载是请保持文章完整性,并以超链接形式注明原始作者“redraiment ”和主站点 地址,谢谢。
联系方式
我的邮箱,欢迎来信(redraiment@gmail.com )
我的Blogger(子清行 ):http://redraiment.blogspot.com/
我的Google Sites(子清行 ):https://sites.google.com/site/redraiment
我的CSDN博客(梦婷轩 ):http://blog.csdn.net/redraiment
我的百度空间(梦婷轩 ):http://hi.baidu.com/redraiment