Unix Shell - How to compute the relative path from the absolute paths?(in bash)

This is Interesting: Free IT Magazines  
Home > Archive > Unix Shell > October 2005 > How to compute the relative path from the absolute paths?(in bash)





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author How to compute the relative path from the absolute paths?(in bash)
PengYu.UT@gmail.com

2005-10-28, 4:53 pm

Hi,

Suppose I know the absolute paths of two directories? How can I compute
the simplest relative path between them?

/home/dir1/b
/home/dir1/c

I want the relative path of b to c is
.../b not ../../dir1/b, etc

Thanks,
Peng

William

2005-10-28, 4:53 pm

<PengYu.UT@gmail.com> wrote in message
news:1130512627.131217.130650@f14g2000cwb.googlegroups.com...
> Hi,
>
> Suppose I know the absolute paths of two directories? How can I compute
> the simplest relative path between them?
>
> /home/dir1/b
> /home/dir1/c
>
> I want the relative path of b to c is
> ../b not ../../dir1/b, etc


Just replace all the common path elements with
a single '..' element. How you do it depends on
your shell and which tools you want to use.

In bourne shell you could set IFS to '/', then
use set, shift and a for loop to compare each
element until you find a difference.

Once you find the difference, you replace
everything up to that point with ../ and add
all the leftover elements from your target
path string.

-Wm






William

2005-10-28, 4:53 pm

"William" <Reply@NewsGroup.Please> wrote in message
news:vtKdnTin2ahp2P_enZ2dnUVZ_s2dnZ2d@gi
ganews.com...
> <PengYu.UT@gmail.com> wrote in message
> news:1130512627.131217.130650@f14g2000cwb.googlegroups.com...
>
> Just replace all the common path elements with
> a single '..' element. How you do it depends on
> your shell and which tools you want to use.
>
> In bourne shell you could set IFS to '/', then
> use set, shift and a for loop to compare each
> element until you find a difference.
>
> Once you find the difference, you replace
> everything up to that point with ../ and add
> all the leftover elements from your target
> path string.


Here's a sample (could use some input validation,
and you might want to restore IFS, etc.):

#!/bin/sh

# Wanted: Relative path from mainPath to target path
mainPath="/etc/dir1/dir2/dir3/b"
target="/etc/dir1/dir2/dir4/c"
relPath=''
IFS='/'
set -- $target
for elem in $mainPath
do
case "$relPath" in
"")
[ "$1" = "$elem" ] || relPath="../$1"
;;
*)
relPath="$relPath/$1"
;;
esac
shift
done

echo "relPath = $relPath"


Alexis Huxley

2005-10-28, 4:53 pm

> Suppose I know the absolute paths of two directories? How can I compute
> the simplest relative path between them?
>
> /home/dir1/b
> /home/dir1/c
>
> I want the relative path of b to c is
> ../b not ../../dir1/b, etc


I have a function to do exactly that. You should be able to see what
you can strip. Not sure this is simplest - the code got patched and
patched and patched over years. Note that, as in your example, the
paths supplied are absolute.

ade_fnm_getrelativity()
{
# Usage: path_from <src_dir> <dst_dir>
# Desc: calculates a relative path from <src_dir> to <dst_dir>

local SRC_DIR DST_DIR SRC_LIST DIR REL_PATH DST_LIST
SRC_DIR=$1
DST_DIR=$2

ade_msg_debug 60 "ade_fnm_getrelativity: original paths $SRC_DIR and $DST_DIR"

{ expr $SRC_DIR : '\/' > /dev/null && expr $DST_DIR : '\/' > /dev/null; } || ade_msg_internalerror "Usage: ade_fnm_getrelativity <abspath> <abspath> (SRC_DIR=$SRC_DIR, DST_DIR=$DST_DIR)"
SRC_DIR=`echo $SRC_DIR | sed 's/^\///'`
DST_DIR=`echo $DST_DIR | sed 's/^\///'`

ade_msg_debug 60 "ade_fnm_getrelativity: leading slash removed paths $SRC_DIR and $DST_DIR"

SRC_LIST=`echo $SRC_DIR | sed 's/\// /g'`
for DIR in $SRC_LIST; do
ade_msg_debug 60 "ade_fnm_getrelativity: checking if paths start with $DIR ..."
expr $DST_DIR : "$DIR/" > /dev/null || expr $DST_DIR : "$DIR\$" > /dev/null || break
SRC_DIR=`echo $SRC_DIR | sed "s/^\\\\($DIR\\\\/\\\\|$DIR\\\$\\\\)//"`
DST_DIR=`echo $DST_DIR | sed "s/^\\\\($DIR\\\\/\\\\|$DIR\\\$\\\\)//"`
done

ade_msg_debug 60 "ade_fnm_getrelativity: reduced paths are '$SRC_DIR' and '$DST_DIR'"

if [ "X$SRC_DIR" = X -a "X$DST_DIR" = X ]; then
REL_PATH=.
else
REL_PATH=`echo $SRC_DIR | sed 's/[^/][^/]*/../g'`/$DST_DIR
fi

ade_msg_debug 60 "ade_fnm_getrelativity: returning $REL_PATH"
echo $REL_PATH

return 0
}


HTH
Alexis
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com