如何使`cd dir / filename`带我到dir /?


10

我发现能够cdfile参数一起使用非常方便。

cd myDirectory/anyname.anyExtension 相当于 cd myDirectory/

实现此行为的最佳别名或函数是什么?

编辑:对不起,我没有在第一名提到它:我用zsh

Answers:


5

在中zsh,我经常这样做:

cd /path/to/somefile(:h)

h用于head)。

如果somefile是符号链接,则还可以执行以下操作:

cd somefile(:A:h)

进入可能找到符号链接目标的目录。


zsh克里斯的相当于现在bash-only的解决办法是:

cd() {
  [[ ! -e $argv[-1] ]] || [[ -d $argv[-1] ]] || argv[-1]=${argv[-1]%/*}
  builtin cd "$@"
}

在中zsh,您还可以重新定义Ctrl-W删除“单词”的内容。

在中zsh,基于单词的运动/转置/删除小部件中的“单词”是数字序列加上$WORDCHARS变量中的字符(默认情况下包括)/

您可以/从中删除,$WORDCHARS以便Ctrl-W仅删除一个路径组件:

WORDCHARS=${WORDCHARS/\/}

另一个有用的扩展是select-word-style小部件,您可以使用该小部件在不同的文字样式之间进行交互选择。

autoload select-word-style
zle -N select-word-style
bindkey '\ew' select-word-style

然后按Alt-W允许您在不同的文字样式之间进行选择。

$ cd /blah/blih<Alt-W>
Word styles (hit return for more detail):
(b)ash (n)ormal (s)hell (w)hitespace (d)efault (q)uit
(B), (N), (S), (W) as above with subword matching
?

有趣。(我也使用zsh)。
塞巴斯蒂安

关于zsh和字样式的功能非常有趣的编辑。也感谢您的zsh命令。它完美地完成了工作。
塞巴斯蒂安

16

我假设如果您输入目录,并且仍在使用,您仍然希望保留其原始功能bash

cd() {
    local file="${!#}"

    if (( "$#" )) && ! [[ -d "$file" ]]; then
        builtin cd "${@:1:($#-1)}" "${file%/*}"
    else
        builtin cd "$@"
    fi
}

如果您永远不会使用cd的选项(-P,等等),那么这也足够了:

cd() { 
    if [ -d "$1" ] || [ -z "$1" ]; then
        builtin cd "$@"
    else
        builtin cd "${1%/*}"
    fi
}

4
如果将函数名称更改为cd,请确保builtincd调用之前添加
Ulrich Dangel,

@克里斯:你右假定;)感谢这个准备使用功能
塞巴斯蒂安

保留cd选项的版本不适用于zsh。比较简单的一个工作正常zsh,但cd已不再等同cd ~:/
塞巴斯蒂安

@Sebastien现在尝试,我认为应该解决该问题。
克里斯·

@Chris,确实添加一个检查就[ -z "$1" ]足够了。我已接受Stephane的回答以使其更具可见性,因为这似乎是的最佳解决方案zsh
塞巴斯蒂安

7

您可以用来dirname从路径中删除文件名,例如

mycd() { cd "$(dirname "$1")"; }

请参阅man dirname


3
请注意,如果您输入目录,则将更改为该目录上方的目录,这可能是不希望的(从目录中不清楚是否需要)。
克里斯·

1
@ChrisDown是的,但是我把它留给了读者作为练习,您的答案显示了如何处理它。
AdrianFrühwirth,2013年

1
@AdrianFrühwirth锻炼!哈哈!

3

如果将其添加到.profile,然后加载(source ~/.profile或注销并再次登录),mycd [file or directory]则将您带到正确的目录:

mycd() { if [ -d "$1" ]; then cd "$1"; else cd "$( dirname "$1" )"; fi ; }

如果您命名cd,那么将会发生奇怪的事情。


1
如果目录名包含空格,并且需要用分号终止命令组,则此操作将中断。为您编辑了它,希望您不要介意。
克里斯·

@ChrisDown,尽管对于其他shell也是这样,但您无需在中使用分号zsh
斯特凡Chazelas

此外,如果将args传递给cd,则也会中断-P
克里斯·

0
cd2() {
 arg=() dir= cmd= IFS=" " msg='[-L|[-P [-e]]|-h] [dir|file]'

 while [ "$#" -gt 1 ] ; do
  case "$1" in
   -h) printf "%s: cd2 %s\n" "$0" "$msg"
    return 1 ;;
   *) arg+=("$1") ;;
  esac
  shift
 done

 [ -f "${1:-}" ] && dir="$(dirname ${1:-})" || dir="${1:A}"
 [ ! -z "$arg" ] && cmd="cd ${arg[@]} $dir" || cmd="cd $dir"

 if ! $cmd 2>/dev/null; then
  printf "%s: cd2 %s\n" "$0" "$msg"
  return 1
 fi
}

给定名为的目录$(sudo reboot),此功能可能会重新引导系统。此外,用户正在使用zsh,而不是bash
库萨兰达

输入任何命令$(sudo reboot),此功能将重新引导系统。另外,+ 1我最初没有注意到'zsh'-不错。
ecwpz91

不,cd '$(sudo reboot)'将更改目录,而您的函数将尝试评估名称。
库萨兰达

嗯,我知道了并进行了更改。让我知道是否可行?接得好。
ecwpz91
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.