问:有没有简单的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)
忘记readlink和realpath,它们可能安装也可能不安装在您的系统上。
在上面扩展dogbane的答案,它被表示为一个函数:
#!/bin/bash
get_abs_filename() {
# $1 : relative filename
echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
}
然后你可以这样使用它:
myabsfile=$(get_abs_filename "../../foo/bar/file.txt")
它是如何工作的,为什么工作?
该解决方案利用了这样一个事实,即Bash内置的pwd命令在调用时不带参数地打印当前目录的绝对路径。
为什么我喜欢这个解?
它是可移植的,并且不需要readlink或realpath,这在给定的Linux/Unix发行版的默认安装中通常不存在。
如果dir不存在呢?
如上所述,如果给定的目录路径不存在,该函数将失败并在stderr上打印。这可能不是你想要的。你可以展开函数来处理这种情况:
#!/bin/bash
get_abs_filename() {
# $1 : relative filename
if [ -d "$(dirname "$1")" ]; then
echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
fi
}
现在如果父dirs不存在,它将返回一个空字符串。
你如何处理拖尾?'或'。输入?
在这种情况下,它确实给出了一条绝对路径,但不是最小路径。它看起来像:
/Users/bob/Documents/..
如果您想解决'..你需要把脚本写成这样:
get_abs_filename() {
# $1 : relative filename
filename=$1
parentdir=$(dirname "${filename}")
if [ -d "${filename}" ]; then
echo "$(cd "${filename}" && pwd)"
elif [ -d "${parentdir}" ]; then
echo "$(cd "${parentdir}" && pwd)/$(basename "${filename}")"
fi
}