假设我有一个文件的路径,如何从命令行引用该文件的目录?

假设我有一个文件的路径,如何从命令行引用该文件的目录?

我可以打字:

dirname ~/home/blah/file.zip

例如,这单独工作得很好,但是当我使用此语法作为某些命令的参数时,它总是将“dirname”读取为所需的目录。 IE:

cd dirname ~/home/blah/file.zip
bash: cd: dirname: No such file or directory

基本上,我如何获得 'dirname文件' 被解读为一个实体?

答案1

cd "$(dirname ~/home/blah/file.zip)"

$(是命令替换的一种形式。这Bash 指南维基有一些关于此过程的好的信息。

答案2

(我不会重复其他答案中已经显示的命令替换功能。)

如果这种情况经常出现,您可以定义一个函数。例如,将其放入您的~/.bashrc

d () {
  if ! [ -d "$1/." ]; then
    set -- "${1%/*}"
  fi
  cd -- "$1"
}

通过这个定义,你可以运行d /path/to/directory改变到指定的目录,或者d /path/to/file改变到包含指定文件的目录(即/path/to)。

对于此特定命令,您可以通过编辑命令来删除最后一个单词:使用默认键绑定,从行尾开始,按Alt+B移回上一个单词,按Alt+D删除右侧的单词。在大多数终端上,从行尾开始,您可以按Esc Backspace直接删除左侧的单词。

如果路径是目录,则~/home/blah/subdir/..指定与 相同的目录~/home/blah

在 zsh 中,您可以(:h)在路径末尾添加标签以去掉文件名并仅保留目录部分。 (它h适用于“head”;t“tail”仅保留文件部分。)您可以使用其他历史修正(:…)路径或 glob 之后。

cd ~/home/blah/file.zip(:h)

答案3

克里斯推荐的形式"$(cmd)"是最安全的,但是这种形式更容易输入并且通常也同样有效:

$ cd `dirname ~/home/blah/file.zip`

区别在于反引号形式可能会混淆通过命令中的某些字符它正在扩展。对于像您所展示的这样的简单命令,您可以立即判断这不会成为问题。对于需要接受任意参数的 shell 脚本,使用双引号$()形式更安全。

答案4

(这只是对 @gilles 答案的回复,因为它太大了,无法发表评论)

正如吉尔斯已经指出的那样,您可以创建一个自动执行所需功能的函数。但您也可以重新定义,而不是使用一些随机名称cd

对于 zsh:

cd() {
    if (( ${#argv} == 1 )) && [[ -f ${1} ]]; then
        builtin cd ${1:h}
    else
        builtin cd "$@"
    fi
}

对于bash:

cd() {
    if [ $# == 1 ] && [[ -f ${1} ]]; then
        builtin cd "$(dirname ${1})"
    else
        builtin cd "$@"
    fi
}

这将允许您执行类似的操作cd /path/to/file,它将自动更改为特定文件的目录。当然,您也可以将 bash 版本与 zsh 一起使用。

相关内容