Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Convert absolute paths to relative paths
- X-seq: zsh-users 4850
- From: Vin Shelton <acs@xxxxxxxxxxxxxxxxxxxx>
- To: Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>
- Subject: Re: Convert absolute paths to relative paths
- Date: Sat, 20 Apr 2002 00:48:20 -0400
- Cc: zsh-users@xxxxxxxxxx
- In-reply-to: <Pine.LNX.4.44.0204191752460.16750-100000@xxxxxxxxxxxxxxxx> (Bart Schaefer's message of "Fri, 19 Apr 2002 17:59:00 -0700 (PDT)")
- Mailing-list: contact zsh-users-help@xxxxxxxxxx; run by ezmlm
- Organization: EtherSoft, Inc
- References: <Pine.LNX.4.44.0204191752460.16750-100000@xxxxxxxxxxxxxxxx>
It turned out I did care about minimizing the path, so here's what I
came up with:
# Print the a relative path from the second directory to the first,
# defaulting the second directory to $PWD if none is specified.
emulate -L zsh
[[ $1 != /* ]] && print $1 && return
local dir=${2:-$PWD}
[[ $1 == $dir ]] && print . && return
local -a cur abs
cur=(${(ps:/:)dir}) # Split 'current' directory into cur
abs=(${(ps:/:)1}) # Split target directory into abs
local min
((min = $#cur < $#abs ? $#cur : $#abs))
local i=1
while ((i <= $min)) && [[ $abs[1] == $cur[$i] ]]
do
abs[1]=() # Strip common prefix from target directory
((i=i+1))
done
# Figure out how many parents to get to common root
local relpath=
while ((i <= $#cur))
do
relpath=../$relpath
((i=i+1))
done
relpath=$relpath${(j:/:)abs}
print ${relpath%/}
Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> writes:
> On Fri, 19 Apr 2002, Vin Shelton wrote:
>
>> Thanks, Bart!
>
> Christoph von Stuckrad pointed out privately that if you try to use this
> to get a relative path to a *file*, rather than to a directory, it will
> go into an infinite loop.
>
> Here's a fix for that:
>
> function relative {
> emulate -L zsh
> local up=.. down
> [[ -d $1 ]] || 2=$1:t 1=$1:h
> [[ -d $1 ]] || return 1
> # ! -d $up/$down accounts for symlinks in $PWD
> while [[ ${PWD#$1} == $PWD || ! -d $up/$down ]]
> do
> up=../$up
> if [[ -n $1:t ]]
> then
> down=$1:t${down:+/$down}
> 1=$1:h
> fi
> done
> print $up/$down${2:+/$2}
> }
- vin
Messages sorted by:
Reverse Date,
Date,
Thread,
Author