我想转换/foo/bar/../ foo
是否有bash命令可以做到这一点?
编辑:在我的实际案例中,目录确实存在。
我想转换/foo/bar/../ foo
是否有bash命令可以做到这一点?
编辑:在我的实际案例中,目录确实存在。
当前回答
我知道这是一个古老的问题。我仍在提供另一种选择。最近我遇到了同样的问题,并且发现没有现有的可移植命令来执行此操作。因此,我编写了下面的shell脚本,其中包括一个可以实现此功能的函数。
#! /bin/sh
function normalize {
local rc=0
local ret
if [ $# -gt 0 ] ; then
# invalid
if [ "x`echo $1 | grep -E '^/\.\.'`" != "x" ] ; then
echo $1
return -1
fi
# convert to absolute path
if [ "x`echo $1 | grep -E '^\/'`" == "x" ] ; then
normalize "`pwd`/$1"
return $?
fi
ret=`echo $1 | sed 's;/\.\($\|/\);/;g' | sed 's;/[^/]*[^/.]\+[^/]*/\.\.\($\|/\);/;g'`
else
read line
normalize "$line"
return $?
fi
if [ "x`echo $ret | grep -E '/\.\.?(/|$)'`" != "x" ] ; then
ret=`normalize "$ret"`
rc=$?
fi
echo "$ret"
return $rc
}
https://gist.github.com/bestofsong/8830bdf3e5eb9461d27313c3c282868c
其他回答
realpath试试。以下是全文来源,特此捐赠给公众领域。
// realpath.c: display the absolute path to a file or directory.
// Adam Liss, August, 2007
// This program is provided "as-is" to the public domain, without express or
// implied warranty, for any non-profit use, provided this notice is maintained.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libgen.h>
#include <limits.h>
static char *s_pMyName;
void usage(void);
int main(int argc, char *argv[])
{
char
sPath[PATH_MAX];
s_pMyName = strdup(basename(argv[0]));
if (argc < 2)
usage();
printf("%s\n", realpath(argv[1], sPath));
return 0;
}
void usage(void)
{
fprintf(stderr, "usage: %s PATH\n", s_pMyName);
exit(1);
}
我不知道是否有直接的bash命令可以做到这一点,但我通常会这样做
normalDir="`cd "${dirToNormalize}";pwd`"
echo "${normalDir}"
而且效果很好。
今天我发现可以使用stat命令来解析路径。
对于"~/Documents"这样的目录:
你可以运行这个:
stat -f %N ~/文档
获取完整路径:
/用户/我/文档
对于符号链接,你可以使用%Y格式选项:
stat -f %Y example_symlink
这可能会返回如下结果:
/usr/local/sbin/example_symlink
格式选项可能在*NIX的其他版本上有所不同,但这些在OSX上对我有用。
一个使用node.js的简单解决方案:
#!/usr/bin/env node
process.stdout.write(require('path').resolve(process.argv[2]));
老问题了,但是如果你在shell级别处理完整路径名,有一个更简单的方法:
abspath="$( cd "$path" && pwd )"
由于cd发生在子shell中,它不会影响主脚本。
假设你的shell内置命令接受-L和-P,有两种变化:
abspath="$( cd -P "$path" && pwd -P )" #physical path with resolved symlinks abspath="$( cd -L "$path" && pwd -L )" #logical path preserving symlinks
就我个人而言,我很少需要这种后面的方法,除非我出于某种原因对符号链接着迷。
供参考:获取脚本起始目录的变体,即使脚本稍后更改了当前目录也能工作。
name0="$(basename "$0")"; #base name of script dir0="$( cd "$( dirname "$0" )" && pwd )"; #absolute starting dir
使用CD可以确保始终拥有绝对目录,即使脚本是通过./script.sh等命令运行的,如果没有CD /pwd,通常只会给出..如果脚本稍后执行cd,则无用。