我想转换/foo/bar/../ foo
是否有bash命令可以做到这一点?
编辑:在我的实际案例中,目录确实存在。
我想转换/foo/bar/../ foo
是否有bash命令可以做到这一点?
编辑:在我的实际案例中,目录确实存在。
当前回答
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
}
注意,这个变体也不需要路径存在。
其他回答
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
}
注意,这个变体也不需要路径存在。
如果您想要从路径中删除部分文件名,“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/../../
在这种情况下,路径不需要存在就可以被规范化。
话多,回答有点晚。我需要写一个,因为我卡住了旧的RHEL4/5。 I处理绝对和相对链接,并简化//,/。/和somedir/../条目。
test -x /usr/bin/readlink || readlink () {
echo $(/bin/ls -l $1 | /bin/cut -d'>' -f 2)
}
test -x /usr/bin/realpath || realpath () {
local PATH=/bin:/usr/bin
local inputpath=$1
local changemade=1
while [ $changemade -ne 0 ]
do
changemade=0
local realpath=""
local token=
for token in ${inputpath//\// }
do
case $token in
""|".") # noop
;;
"..") # up one directory
changemade=1
realpath=$(dirname $realpath)
;;
*)
if [ -h $realpath/$token ]
then
changemade=1
target=`readlink $realpath/$token`
if [ "${target:0:1}" = '/' ]
then
realpath=$target
else
realpath="$realpath/$target"
fi
else
realpath="$realpath/$token"
fi
;;
esac
done
inputpath=$realpath
done
echo $realpath
}
mkdir -p /tmp/bar
(cd /tmp ; ln -s /tmp/bar foo; ln -s ../.././usr /tmp/bar/link2usr)
echo `realpath /tmp/foo`
我不知道是否有直接的bash命令可以做到这一点,但我通常会这样做
normalDir="`cd "${dirToNormalize}";pwd`"
echo "${normalDir}"
而且效果很好。
基于loveborg出色的python代码片段,我这样写:
#!/bin/sh
# Version of readlink that follows links to the end; good for Mac OS X
for file in "$@"; do
while [ -h "$file" ]; do
l=`readlink $file`
case "$l" in
/*) file="$l";;
*) file=`dirname "$file"`/"$l"
esac
done
#echo $file
python -c "import os,sys; print os.path.abspath(sys.argv[1])" "$file"
done