I have a lot of relative symbolic links that I want to move to another directory.
How can I move symbolic links (those with a relative path) while preserving the right path?
I have a lot of relative symbolic links that I want to move to another directory.
How can I move symbolic links (those with a relative path) while preserving the right path?
You can turn relative paths into full paths using readlink -f foo
. So you would do something like:
ln -s $(readlink -f $origlink) $newlink
rm $origlink
EDIT:
I noticed that you wish to keep the paths relative. In this case, after you move the link, you can use symlinks -c
to convert the absolute paths back into relative paths.
-r
option of ln
to have it create a relative link, i.e. ln -sr "$(readlink -f "$origlink")" "$newlink"; rm "$origlink"
. –
Pipeline ln -rs "$(readlink -f "$origlink")" "$newlink"
–
Multipurpose symlinks
utility available, you can use the -r
option of ln
to convert an existing absolute symlink to a relative one. ln -srf $newlink
. Or just do what @Pipeline suggests and just create a relative symlink in the first step. –
Greenish readlink
has no option -f
, so you have to brew install coreutils
and use greadlink
, instead. –
Neisse This is a perl
solution that preserves relative paths:
use strictures;
use File::Copy qw(mv);
use Getopt::Long qw(GetOptions);
use Path::Class qw(file);
use autodie qw(:all GetOptions mv);
my $target;
GetOptions('target-directory=s' => \$target);
die "$0 -t target_dir symlink1 symlink2 symlink3\n" unless $target && -d $target;
for (@ARGV) {
unless (-l $_) {
warn "$_ is not a symlink\n";
next;
}
my $newlink = file(readlink $_)->relative($target)->stringify;
unlink $_;
symlink $newlink, $_;
mv $_, $target;
}
Use ln
of course:
for i in *; do # or whatever pattern you're wanting to match
ln -sr "$(readlink "$i")" newdir/"$i";
done;
I was surprised this works, but LN(1)
must be smart enough to take note of what's going on and help you out! I even tried it with a "newdir" of ../somethingelse
(which should be a no-op in the link re-writing) and ..
(which will remove a ..
from the link target), and it worked wonderfully.
Improving on Christopher Neylan's answer:
~/bin $ cat mv_ln
#!/bin/bash
#
# inspired by https://mcmap.net/q/416287/-how-do-i-move-a-relative-symbolic-link#8523293
# by Christopher Neylan
help() {
echo 'usage: mv_ln src_ln dest_dir'
echo ' mv_ln --help'
echo
echo ' Move the symbolic link src_ln into dest_dir while'
echo ' keeping it relative'
exit 1
}
[ "$1" == "--help" ] || [ ! -L "$1" ] || [ ! -d "$2" ] && help
set -e # exit on error
orig_link="$1"
orig_name=$( basename "$orig_link" )
orig_dest=$( readlink -f "$orig_link" )
dest_dir="$2"
ln -r -s "$orig_dest" "$dest_dir/$orig_name"
rm "$orig_link"
This is also part of https://github.com/tpo/little_shell_scripts
$(…)
–
Multipurpose $( )
would have a negative/unexpected impact? –
Geotaxis orig_link="$1"
. I just did some test, and I could not get it to break, may be I just put them in out of habit, because I find it easier to remember a simple rule, that avoids bugs, than a set of many rules. –
Multipurpose One can use tar
to move a folder containing relative symbolic links.
For example:
cd folder_to_move/..
tar czvf files.tgz folder_to_move
cd dest_folder/..
tar xzvf /absolute/path/to/folder_to_move/../files.tgz
# If all is fine, clean-up
rm /absolute/path/to/folder_to_move/../files.tgz
rm -rf /absolute/path/to/folder_to_move
cd folder_to_move; tar cf - . | (cd /usr/local/dest_folder; tar xf -)
–
Olney © 2022 - 2024 — McMap. All rights reserved.