coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: command for relative path


From: Dmitry V. Levin
Subject: Re: command for relative path
Date: Sun, 13 Nov 2011 22:45:28 +0400

Hi,

On Sat, Nov 12, 2011 at 11:45:56AM -0700, Eric Blake wrote:
[...]
> http://docs.python.org/library/os.path.html
> >> os.path.relpath(path[, start])
> >> 
> >>     Return a relative filepath to path either from the current directory 
> >> or from an optional start point.
> 
> Ah, so the idea is that python has a function that computes a relative
> pathname to one path given a starting point:
> 
> $ relpath /usr/bin /tmp
> ../usr/bin
> $ relpath /usr/bin /usr/share
> ../bin

Btw, there is an utility in freebsd ports called relpath:
http://www.freebsd.org/cgi/cvsweb.cgi/ports/sysutils/relpath/
ftp://ftp.freebsd.org/pub/FreeBSD/ports/local-distfiles/beech/relpath-0.1.0.tar.gz

$ lftp -c 'cat 
http://www.freebsd.org/cgi/cvsweb.cgi/~checkout~/ports/sysutils/relpath/pkg-descr'
Usage: relpath [-d DIR] START_DIR END_PATH                                      
                                      

Find a relative path from START_DIR to END_PATH.
Prints the relative path on standard out.

If -d DIR, then only emit a relative path if both
START_DIR and END_PATH are sub-directories of DIR;
otherwise, emit an absolute path to END_PATH.

> This seems like you could do it in shell without resorting to python, by
> computing a canonical name for both the destination and the starting
> point, then comparing common prefixes, and for every directory component
> that differs after the common prefix, replacing the directory with
> '../'.  This has been done before; for example, this is from gnulib-tool:
> 
> # func_relativize DIR1 DIR2
> # computes a relative pathname RELDIR such that DIR1/RELDIR = DIR2.
> # Input:
> # - DIR1            relative pathname, relative to the current directory
> # - DIR2            relative pathname, relative to the current directory
> # Output:
> # - reldir          relative pathname of DIR2, relative to DIR1
> func_relativize ()
> {
>   dir0=`pwd`
>   dir1="$1"
>   dir2="$2"
>   sed_first='s,^\([^/]*\)/.*$,\1,'
>   sed_rest='s,^[^/]*/*,,'
>   sed_last='s,^.*/\([^/]*\)$,\1,'
>   sed_butlast='s,/*[^/]*$,,'
>   while test -n "$dir1"; do
>     first=`echo "$dir1" | sed -e "$sed_first"`
>     if test "$first" != "."; then
>       if test "$first" = ".."; then
>         dir2=`echo "$dir0" | sed -e "$sed_last"`/"$dir2"
>         dir0=`echo "$dir0" | sed -e "$sed_butlast"`
>       else
>         first2=`echo "$dir2" | sed -e "$sed_first"`
>         if test "$first2" = "$first"; then
>           dir2=`echo "$dir2" | sed -e "$sed_rest"`
>         else
>           dir2="../$dir2"
>         fi
>         dir0="$dir0"/"$first"
>       fi
>     fi
>     dir1=`echo "$dir1" | sed -e "$sed_rest"`
>   done
>   reldir="$dir2"
> }
> 
> Doing it in fewer processes seems possible with something like a single
> awk script, although I haven't tried writing one; at any rate, awk would
> be more portable than python for the same task.
> 
> But yes, providing this as an alternative mode of coreutils' realpath
> instead of scripting it in shell or awk seems like a useful addition -
> would you care to submit a patch?

AFAIR the coreutils' realpath is called readlink. ;)

Would "readlink --relative" or something like this be a good choice?
Or should it rather be a new utility?


-- 
ldv

Attachment: pgpUtJHCjfdDU.pgp
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]