如何通过Shell(BASH/ZSH/SH)获取文件的绝对路径?

704

问题:是否有一个简单的sh/bash/zsh/fish/...命令,可以打印出我输入的任何文件的绝对路径?

使用场景:我在目录/a/b中,我想要在命令行中打印文件c的完整路径,以便我可以轻松地将其粘贴到另一个程序中:/a/b/c。这很简单,但是编写一个小程序来完成此任务可能会为我节省5秒钟左右的时间,当处理长路径时这些时间最终会相加。所以让我感到惊讶的是,我找不到一个标准的实用程序来完成这个任务 - 确实没有吗?

这里是一个示例实现,abspath.py:

#!/usr/bin/python
# Author: Diggory Hardy <diggory.hardy@gmail.com>
# Licence: public domain
# Purpose: print the absolute path of all input paths

import sys
import os.path
if len(sys.argv)>1:
    for i in range(1,len(sys.argv)):
        print os.path.abspath( sys.argv[i] )
    sys.exit(0)
else:
    print >> sys.stderr, "Usage: ",sys.argv[0]," PATH."
    sys.exit(1)

我认为@DennisWilliamson的回答(使用-m选项)更优秀,因为它通常更具可移植性,并且可以处理不存在的文件。 - TTT
或者Flimm的答案也很好; 但是Bannier的回答最符合我的原始问题。 - dhardy
3
苹果电脑用户请查看此答案。链接 - Ian
可能是重复的问题Bash: 获取相对路径的绝对路径 - user
23个回答

1
在zsh中,是的有这个功能。
假设你的路径存储在一个变量中,你可以使用:P修饰符来获取文件的绝对路径。
示例:
f='../example.txt'
echo ${f:P}

以上代码将打印出 "../example.txt" 的绝对路径。
你也可以选择使用 ":A" 修饰符来进一步解析符号链接,但这取决于是否安装了 "realpath"。
f='../example.txt'
echo ${f:A}

参见https://zsh.sourceforge.io/Doc/Release/Expansion.html#Modifiers


0

我使用单行

(cd ${FILENAME%/*}; pwd)

然而,这只能在$FILENAME具有任何类型(相对或绝对)的前导路径(实际存在)时使用。如果根本没有前导路径,则答案就是简单的$PWD。如果前导路径不存在,则答案可能不确定,否则答案就是${FILENAME%/*},如果路径是绝对的。

将所有这些放在一起,我建议使用以下函数

function abspath() {
  # argument 1: file pathname (relative or absolute)
  # returns: file pathname (absolute)
  if [ "$1" == "${1##*/}" ]; then # no path at all
    echo "$PWD"
  elif [ "${1:0:1}" == "/" -a "${1/../}" == "$1" ]; then # strictly absolute path
    echo "${1%/*}"
  else # relative path (may fail if a needed folder is non-existent)
    echo "$(cd ${1%/*}; pwd)"
  fi
}

请注意,这仅适用于和兼容的shell。我不认为这些替换在简单的shell sh中有效。

-1

嘿,大家好。我知道这是一个旧帖子,但我只是为了参考其他像我一样访问这个帖子的人而发布这篇文章。如果我正确理解了问题,我认为locate $filename命令可以显示所提供文件的绝对路径,但前提是该文件存在。


5
locate是一种通过名称搜索文件/路径的实用工具。它可以完成任务,但也可能会找到其他匹配项,并且如果不先以root身份调用updatedb,可能无法找到现有文件。 - dhardy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接