是否有一个命令来检索给定相对路径的绝对路径?
例如,我想要$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
当前回答
不管怎样,我投票给了被选中的答案,但我想分享一个解决方案。缺点是,它只适用于Linux——在出现堆栈溢出之前,我花了大约5分钟的时间试图找到OSX的等效版本。但我相信它就在那里。
在Linux上,可以将readlink -e与dirname结合使用。
$(dirname $(readlink -e ../../../../etc/passwd))
收益率
/etc/
然后你用dirname的姐妹,basename 文件名
$(basename ../../../../../passwd)
收益率
passwd
把它们放在一起…
F=../../../../../etc/passwd
echo "$(dirname $(readlink -e $F))/$(basename $F)"
收益率
/etc/passwd
如果目标目录是安全的,basename将不会返回任何内容 在最终输出中,你只会得到双斜杠。
其他回答
类似于@ernest-a的答案,但不影响$OLDPWD或定义一个新函数,您可以触发一个子shell (cd <path>;pwd)
$ pwd
/etc/apache2
$ cd ../cups
$ cd -
/etc/apache2
$ (cd ~/..; pwd)
/Users
$ cd -
/etc/cups
蓝光:
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
欧根的回答对我来说不太管用,但这个却管用:
absolute="$(cd $(dirname \"$file\"); pwd)/$(basename \"$file\")"
旁注,当前工作目录不受影响。
在find的情况下,可能最简单的是给它搜索的绝对路径,例如:
find /etc
find `pwd`/subdir_of_current_dir/ -type f
对@ernest-a相当不错的版本的改进:
absolute_path() {
cd "$(dirname "$1")"
case $(basename $1) in
..) echo "$(dirname $(pwd))";;
.) echo "$(pwd)";;
*) echo "$(pwd)/$(basename $1)";;
esac
}
这正确地处理了路径的最后一个元素是..,在这种情况下,@ernest-a的答案中的“$(pwd)/$(basename“$1”)”将通过作为accurate_sub_path/spurious_subdirectory/…