我想转换/foo/bar/../ foo
是否有bash命令可以做到这一点?
编辑:在我的实际案例中,目录确实存在。
我想转换/foo/bar/../ foo
是否有bash命令可以做到这一点?
编辑:在我的实际案例中,目录确实存在。
当前回答
今天我发现可以使用stat命令来解析路径。
对于"~/Documents"这样的目录:
你可以运行这个:
stat -f %N ~/文档
获取完整路径:
/用户/我/文档
对于符号链接,你可以使用%Y格式选项:
stat -f %Y example_symlink
这可能会返回如下结果:
/usr/local/sbin/example_symlink
格式选项可能在*NIX的其他版本上有所不同,但这些在OSX上对我有用。
其他回答
如果您想要从路径中删除部分文件名,“dirname”和“basename”是您的朋友,“realpath”也很方便。
dirname /foo/bar/baz
# /foo/bar
basename /foo/bar/baz
# baz
dirname $( dirname /foo/bar/baz )
# /foo
realpath ../foo
# ../foo: No such file or directory
realpath /tmp/../tmp/../tmp
# /tmp
realpath替代品
如果您的shell不支持realpath,您可以尝试
readlink -f /path/here/..
Also
readlink -m /path/there/../../
工作原理与
realpath -s /path/here/../../
在这种情况下,路径不需要存在就可以被规范化。
FILEPATH="file.txt"
echo $(realpath $(dirname $FILEPATH))/$(basename $FILEPATH)
即使文件不存在,这也可以工作。它需要包含该文件的目录存在。
realpath的问题是它在BSD(或OSX)上不可用。下面是一个简单的配方,摘自Linux Journal上一篇相当古老(2009年)的文章,它是相当可移植的:
function normpath() {
# Remove all /./ sequences.
local path=${1//\/.\//\/}
# Remove dir/.. sequences.
while [[ $path =~ ([^/][^/]*/\.\./) ]]; do
path=${path/${BASH_REMATCH[0]}/}
done
echo $path
}
注意,这个变体也不需要路径存在。
一个使用node.js的简单解决方案:
#!/usr/bin/env node
process.stdout.write(require('path').resolve(process.argv[2]));
今天我发现可以使用stat命令来解析路径。
对于"~/Documents"这样的目录:
你可以运行这个:
stat -f %N ~/文档
获取完整路径:
/用户/我/文档
对于符号链接,你可以使用%Y格式选项:
stat -f %Y example_symlink
这可能会返回如下结果:
/usr/local/sbin/example_symlink
格式选项可能在*NIX的其他版本上有所不同,但这些在OSX上对我有用。