用目标替换符号链接

用目标替换符号链接

在 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

相关内容