
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
以下は、chmeeeの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