
Как можно заменить все символические ссылки в каталоге (и дочерних) на их цели в Mac OS X? Если цель недоступна, я бы предпочел оставить мягкую ссылку в покое.
решение1
Если вы используете псевдонимы Mac OSX, то find . -type l
ничего не выйдет.
Вы можете использовать следующий скрипт [Node.js] для перемещения/копирования целей ваших символических ссылок в другой каталог:
fs = require('fs')
path = require('path')
sourcePath = 'the path that contains the symlinks'
targetPath = 'the path that contains the targets'
outPath = 'the path that you want the targets to be moved to'
fs.readdir sourcePath, (err,sourceFiles) ->
throw err if err
fs.readdir targetPath, (err,targetFiles) ->
throw err if err
for sourceFile in sourceFiles
if sourceFile in targetFiles
targetFilePath = path.join(targetPath,sourceFile)
outFilePath = path.join(outPath,sourceFile)
console.log """
Moving: #{targetFilePath}
to: #{outFilePath}
"""
fs.renameSync(targetFilePath,outFilePath)
# if you don't want them oved, you can use fs.cpSync instead
решение2
Вот версииЧмииответ, который использует readlink
и будет работать правильно, если в имени файла есть пробелы:
Новое имя файла соответствует старому имени ссылки:
find . -type l | while read -r link
do
target=$(readlink "$link")
if [ -e "$target" ]
then
rm "$link" && cp "$target" "$link" || echo "ERROR: Unable to change $link to $target"
else
# remove the ": # " from the following line to enable the error message
: # echo "ERROR: Broken symlink"
fi
done
Новое имя файла совпадает с именем цели:
find . -type l | while read -r link
do
target=$(readlink "$link")
# using readlink here along with the extra test in the if prevents
# attempts to copy files on top of themselves
new=$(readlink -f "$(dirname "$link")/$(basename "$target")")
if [ -e "$target" -a "$new" != "$target" ]
then
rm "$link" && cp "$target" "$new" || echo "ERROR: Unable to change $link to $new"
else
# remove the ": # " from the following line to enable the error message
: # echo "ERROR: Broken symlink or destination file already exists"
fi
done
решение3
Вы не сказали, какие имена должны иметь файлы после замены.
Этот скрипт считает, что замененные ссылки должны иметь те же имена, которые у них были как у ссылок.
for link in `find . -type l`
do
target=`\ls -ld $link | sed 's/^.* -> \(.*\)/\1/'`
test -e "$target" && (rm "$link"; cp "$target" "$link")
done
Если вы хотите, чтобы файлы имели то же имя, что и цель, этого должно быть достаточно.
for link in `find . -type l`
do
target=`\ls -ld $link | sed 's/^.* -> \(.*\)/\1/'`
test -e "$target" && (rm $link; cp "$target" `dirname "$link"`/`basename "$target"`)
done