zsh-users
 help / color / mirror / code / Atom feed
* Converting absolut symlinks to relative ones...?
@ 2016-03-06 13:20 Meino.Cramer
  2016-03-06 17:39 ` Danek Duvall
  0 siblings, 1 reply; 5+ messages in thread
From: Meino.Cramer @ 2016-03-06 13:20 UTC (permalink / raw)
  To: zsh-users

Hi,

following "problem":

At some point in a directory tree there is a file (the reference), 
which is physically copied multiple times into that
tree below that point at different nesting depths.

I want to create a script which will find those files
(already done) and replace those files with a symlink to the
reference file.

Since I dont know of a simple way to calculate the "difference"
of two absolute paths to create a relative path to the reference from the point of
view of its current copy, I came across the idea to create symlinks
with absolute paths to the reference in a first step and hope that there is a
zsh/system/linux utility which will create relative symlinks afterwards...

This idea has one drawback: I dont know of such an utility... ;)


Is there such an utility or is there even an utility which magically do that all
in one turn?

Thank you very much in advance for any help!
Best regards,
Meino





^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Converting absolut symlinks to relative ones...?
  2016-03-06 13:20 Converting absolut symlinks to relative ones...? Meino.Cramer
@ 2016-03-06 17:39 ` Danek Duvall
  2016-03-06 19:38   ` Bart Schaefer
  0 siblings, 1 reply; 5+ messages in thread
From: Danek Duvall @ 2016-03-06 17:39 UTC (permalink / raw)
  To: Meino.Cramer; +Cc: zsh-users

On Sun, Mar 06, 2016 at 02:20:13PM +0100, Meino.Cramer@gmx.de wrote:

> Hi,
> 
> following "problem":
> 
> At some point in a directory tree there is a file (the reference), 
> which is physically copied multiple times into that
> tree below that point at different nesting depths.
> 
> I want to create a script which will find those files
> (already done) and replace those files with a symlink to the
> reference file.
> 
> Since I dont know of a simple way to calculate the "difference"
> of two absolute paths to create a relative path to the reference from the point of
> view of its current copy, I came across the idea to create symlinks
> with absolute paths to the reference in a first step and hope that there is a
> zsh/system/linux utility which will create relative symlinks afterwards...
> 
> This idea has one drawback: I dont know of such an utility... ;)

GNU ln has a -r option which does this.

Danek


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Converting absolut symlinks to relative ones...?
  2016-03-06 17:39 ` Danek Duvall
@ 2016-03-06 19:38   ` Bart Schaefer
  2016-03-06 20:21     ` Danek Duvall
  0 siblings, 1 reply; 5+ messages in thread
From: Bart Schaefer @ 2016-03-06 19:38 UTC (permalink / raw)
  To: zsh-users

On Mar 6,  9:39am, Danek Duvall wrote:
}
} GNU ln has a -r option which does this.

That must be a very recent addition, there's no sign of it in coreutils
8.13 from 2011 (on my Ubuntu box).

ln-r () {
  emulate -L zsh
  local symlink
  local -a here there route common
  for symlink in $@:a
  do
    [[ -h $symlink ]] || continue
    common=()
    route=()
    if [[ -d $symlink ]]
    then here=( ${(s:/:)symlink} )
    else here=( ${(s:/:)symlink:h} )
    fi
    there=( ${(s:/:)symlink:A} )
    while (( $#here && $#there ))
    do
      if (( $#route))
      then route=( .. $route $there[1] )
      elif [[ $here[1] == $there[1] ]]
      then
        common+=( $here[1] )
      else
        if [[ -d $symlink || -z $common ]]
        then route=( $there[1] )
        else route=( .. $there[1] )
        fi
      fi
      shift here
      shift there
    done
    if (( $#common ))
    then route+=( $there )
    else continue # no common prefix, absolute link is best
    fi
    # Remove the "print" and both (qq) to actually do linking
    print ln -fs "${(qq)${(j:/:)route}:-.}" "${(qq)symlink}"
  done
}

To change the "no common prefix" behavior, change the loop to become
"while (( $#here || $#there ))" and remove references to $common.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Converting absolut symlinks to relative ones...?
  2016-03-06 19:38   ` Bart Schaefer
@ 2016-03-06 20:21     ` Danek Duvall
  2016-03-06 21:22       ` Vin Shelton
  0 siblings, 1 reply; 5+ messages in thread
From: Danek Duvall @ 2016-03-06 20:21 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-users

On Sun, Mar 06, 2016 at 11:38:30AM -0800, Bart Schaefer wrote:

> On Mar 6,  9:39am, Danek Duvall wrote:
> }
> } GNU ln has a -r option which does this.
> 
> That must be a very recent addition, there's no sign of it in coreutils
> 8.13 from 2011 (on my Ubuntu box).

Looks like it arrived in 8.16, in March 2012.

> ln-r () {
> ...

Might be a useful addition to the ln in zsh/files, too.

Danek


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Converting absolut symlinks to relative ones...?
  2016-03-06 20:21     ` Danek Duvall
@ 2016-03-06 21:22       ` Vin Shelton
  0 siblings, 0 replies; 5+ messages in thread
From: Vin Shelton @ 2016-03-06 21:22 UTC (permalink / raw)
  To: Danek Duvall, Bart Schaefer, zsh-users

[-- Attachment #1: Type: text/plain, Size: 588 bytes --]

On Sun, Mar 6, 2016 at 3:21 PM, Danek Duvall <duvall@comfychair.org> wrote:
> On Sun, Mar 06, 2016 at 11:38:30AM -0800, Bart Schaefer wrote:
>
>> On Mar 6,  9:39am, Danek Duvall wrote:
>> }
>> } GNU ln has a -r option which does this.
>>
>> That must be a very recent addition, there's no sign of it in coreutils
>> 8.13 from 2011 (on my Ubuntu box).
>
> Looks like it arrived in 8.16, in March 2012.
>
>> ln-r () {
>> ...
>
> Might be a useful addition to the ln in zsh/files, too.
>
> Danek

I don't know what is needed, but attached is the function I use to
calculate a relative path.

[-- Attachment #2: relative --]
[-- Type: application/octet-stream, Size: 1041 bytes --]

# 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 || return 1

[[ $1 != /* ]] && print $1 && return 0
[[ -f $1 ]] && 3=$1:t 1=$1:h
[[ ( -d $1 || -L $1 ) && -d ${2:=$PWD} ]] || return 1
[[ $1 -ef $2 ]] && print ${3:-.} && return 0

# The simplest way to eliminate symlinks and ./ and ../ in the paths:
#1=$(cd $1; pwd -r)
#2=$(cd $2; pwd -r)

local -a cur abs
cur=( ${(s:/:)2} )              # Split 'current' directory into cur
abs=( ${(s:/:)1} $3 )           # Split target directory into abs

# Compute the length of the common prefix, or discover a subdirectory:
integer i=1
while [[ i -le $#abs && $abs[i] == $cur[i] ]]; do
  ((++i > $#cur)) && print ${(j:/:)abs[i,-1]} && return
done

2=${(j:/:)cur[i,-1]/*/..}       # Up to the common prefix directory and
1=${(j:/:)abs[i,-1]}            # down to the target directory or file

print $2${1:+/$1}

# Local Variables:
# mode: shell-script
# sh-indentation: 2
# indent-tabs-mode: nil
# End:

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-03-06 21:22 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-06 13:20 Converting absolut symlinks to relative ones...? Meino.Cramer
2016-03-06 17:39 ` Danek Duvall
2016-03-06 19:38   ` Bart Schaefer
2016-03-06 20:21     ` Danek Duvall
2016-03-06 21:22       ` Vin Shelton

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).