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

Séb*_*ien 10 shell cd-command

我会发现能够cd文件参数一起使用非常方便。

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

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

编辑:对不起,我没有在第一个地方提到它:我使用zsh

Chr*_*own 16

我假设如果您输入一个目录,并且您正在使用bash.

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

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

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

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

  • 如果您将函数名称更改为 cd 确保在 `cd` 调用前添加 `builtin` (4认同)

Adr*_*rth 7

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

mycd() { cd "$(dirname "$1")"; }
Run Code Online (Sandbox Code Playgroud)

man dirname

  • 请注意,如果您输入一个目录,这将更改为该目录 *above* 的目录,这可能是不需要的(从问题中不清楚是否需要)。 (3认同)

Sté*_*las 5

zsh,我经常这样做:

cd /path/to/somefile(:h)
Run Code Online (Sandbox Code Playgroud)

h对于head)。

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

cd somefile(:A:h)
Run Code Online (Sandbox Code Playgroud)

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


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

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

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

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

您可以删除/from$WORDCHARS以便Ctrl-W只删除一个路径组件:

WORDCHARS=${WORDCHARS/\/}
Run Code Online (Sandbox Code Playgroud)

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

autoload select-word-style
zle -N select-word-style
bindkey '\ew' select-word-style
Run Code Online (Sandbox Code Playgroud)

然后按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
?
Run Code Online (Sandbox Code Playgroud)