replace all symlinks with original
a related answer, this solution keeps the file at it's original place and creates a copy in place of the symlink
#/bin/bash
for f in $(find . -maxdepth 1 -type l)
do
cp --remove-destination $(readlink -e $f) $f
done
You can do this easily with rsync:
rsync symdir/ symdir_output/ -a --copy-links -v
(-a means preserve basically every detail about the files, --copy-links overrides -a to turn symlinks into the real files/directories, and -v is for verbose)
Edit:
Sorry, my solution doesn't do exactly what you asked for. It will preserve the symlink's names instead of using the destination names. symdir_output would have sym1 and sym2 instead of dir1 and dir2 (though sym1 and sym2 would be a real copy of dir1 and dir2). Hope it still works for you.
Probably not the best way, but it works:
#!/usr/bin/bash
for link in $(find /symdir -type l)
do
loc="$(dirname "$link")"
dir="$(readlink "$link")"
mv "$dir" "$loc"
rm "$link"
done
My very personal trick for files (not directories):
sed -i '' **/*
Note that I'm using **
which uses the bash globstar option, you may have to enable it beforehand:
shopt -s globstar
How it works
I trick sed
to do the job, by using an implementation detail of the sed
inplace mode.
sed
is a tool to edit streams of text. The -i
option of sed
means inplace
, the empty string ''
is the instruction set: so there's no instruction, sed
will do nothing. **/*
is a bash globstar
pattern meaning "all files and all folders, at all depth, from here".
The algorithm sed
uses to edit a file inplace is:
- Create a temporary file as the output file,
- for each line in the input file:
- apply the transformation, write to the output file.
- Move the output file over the input file.
As I'm asking no transformations (the empty string), the algorithm can be simplified as:
- Create a temporary file,
- copy the content of the original file to the temporary file
- move the temporary file over the original file.
The temporary file is a real file, sed
completly ignores that the input file was a symlink, it just reads it. So at the last step, when sed
moves the temporary file over the real file, it "overwrite" the symlink with a real file, that's what we wanted.
This also explains why it won't work to transform a "symlink to a directory" to a real directory: sed
works on file contents.