是否有一个命令来检索给定相对路径的绝对路径?
例如,我想要$line包含dir ./etc/中每个文件的绝对路径
find ./ -type f | while read line; do
echo $line
done
是否有一个命令来检索给定相对路径的绝对路径?
例如,我想要$line包含dir ./etc/中每个文件的绝对路径
find ./ -type f | while read line; do
echo $line
done
当前回答
如果相对路径是一个目录路径,那么试试我的,应该是最好的:
absPath=$(pushd ../SOME_RELATIVE_PATH_TO_Directory > /dev/null && pwd && popd > /dev/null)
echo $absPath
其他回答
下面是一个相当短的函数,可以用来完全绝对化和规范化任何给定的输入路径,只使用POSIX shell和readlink语义:
canonicalize_path() {
(
FILEPATH="$1"
for _ in 1 2 3 4 5 6 7 8; # Maximum symlink recursion depth
do
cd -L "`case "${FILEPATH}" in */*) echo "${FILEPATH%/*}";; *) echo ".";; esac`/" # cd $(dirname)
if ! FILEPATH="$(readlink "${FILEPATH##*/}" || ( echo "${FILEPATH##*/}" && false ) )";
then
break
fi
done
cd -P "." || return $?
echo "$(pwd)/${FILEPATH}"
)
}
如果引用的文件不存在,则只解析指向最终文件名的目录路径。如果指向该文件路径的任何目录都不存在,将返回一个cd错误。这恰好是它试图模拟的GNU/Linux readlink -f命令的确切语义。
在bash/zsh中,您还可以将数字列表压缩为{1..8}或类似的。之所以选择8这个数字,是因为这是Linux多年来的最大限制,后来在4.2版本中将整个路径的分辨率限制为40。如果达到了分辨率限制,代码不会失败,而是返回最后考虑的路径——但是可以添加显式的[- l "${FILEPATH}"]检查来检测这种情况。
这段代码也可以很容易地重用,以确保当前工作目录与已执行脚本在文件系统中的位置匹配(shell脚本的常见需求),只需删除函数和子shell包装器:
FILEPATH="$0"
for _ in 1 2 3 4 5 6 7 8; # Maximum symlink recursion depth
do
cd -L "`case "${FILEPATH}" in */*) echo "${FILEPATH%/*}";; *) echo ".";; esac`/" # cd $(dirname)
if ! FILEPATH="$(readlink "${FILEPATH##*/}" || ( echo "${FILEPATH##*/}" && false ) )";
then
break
fi
done
cd -P "."
FILEPATH="$(pwd)/${FILEPATH}"
蓝光:
cd $relative_path ; pwd
这里有一个POSIX兼容的解释(我认为),所以它应该在任何平台上工作。
当然,这是可编写脚本的,但我认为分解它可能会使一些人更容易理解/修改特定的用例。
你可以使用which, locate, find,全路径等等。
x = your_file_name
$ x="nvi"
文件容易指示符号链接
$ file -h `which $x`
/usr/local/bin/nvi: symbolic link to ../Cellar/nvi/1.81.6_5/bin/nvi
接下来,稍微改变一下输出,这样我们就得到了一个“完整的”相对路径。 在这个例子中,我们只需要去掉中间的部分。
注意大写Y和小写x。可能有更简洁的方法。
$ Y=$(file -h `which $x` | sed "s/$x: symbolic link to //")
$ echo $Y
/usr/local/bin/../Cellar/nvi/1.81.6_5/bin/nvi
使用dirname,我们只得到路径部分。CD给它,名字就会自己清理干净。
$ cd `dirname $Y` ; pwd
/usr/local/Cellar/nvi/1.81.6_5/bin
这将我们引向UNIX的老技巧,即通过在括号/子shell中执行所有操作来“幽灵巡视”目录。这将有效地将我们返回到当前目录。
为了完整起见,我们可以将实际的文件名粘回末尾。
Ls甚至确保绝对路径是有效的,这是额外的加分。
$ ( cd `dirname ${Y}` ; ls `pwd`/${x} )
/usr/local/Cellar/nvi/1.81.6_5/bin/nvi
所以/usr/local/bin/nvi实际上是/usr/local/Cellar/nvi/1.81.6_5/bin/nvi
快速“转换”路径的简化示例:
$ (cd /usr/local/bin/../Cellar/nvi/1.81.6_5/bin ; pwd)
/usr/local/Cellar/nvi/1.81.6_5/bin
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/file.html https://pubs.opengroup.org/onlinepubs/9699919799/utilities/dirname.html
在find的情况下,可能最简单的是给它搜索的绝对路径,例如:
find /etc
find `pwd`/subdir_of_current_dir/ -type f
use:
find "$(pwd)"/ -type f
获取所有文件或
echo "$(pwd)/$line"
显示完整路径(如果相对路径关系到)
如果相对路径是一个目录路径,那么试试我的,应该是最好的:
absPath=$(pushd ../SOME_RELATIVE_PATH_TO_Directory > /dev/null && pwd && popd > /dev/null)
echo $absPath