Ersetzen Sie den symbolischen Link durch das Ziel.

Ersetzen Sie den symbolischen Link durch das Ziel.

Wie können Sie unter Mac OS X alle symbolischen Links in einem Verzeichnis (und untergeordneten Verzeichnissen) durch ihre Ziele ersetzen? Wenn das Ziel nicht verfügbar ist, würde ich den Softlink lieber unverändert lassen.

Antwort1

Wenn Sie Aliase für Mac OSX verwenden, wird find . -type lnichts angezeigt.

Mit dem folgenden [Node.js]-Skript können Sie die Ziele Ihrer symbolischen Links in ein anderes Verzeichnis verschieben/kopieren:

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

Antwort2

Hier sind Versionen vonchmeeesAntwort, die verwendet wird readlinkund ordnungsgemäß funktioniert, wenn ein Dateiname Leerzeichen enthält:

Neuer Dateiname entspricht altem Linknamen:

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

Neuer Dateiname entspricht Zielname:

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

Antwort3

Sie haben nicht gesagt, welche Namen die Dateien nach dem Ersetzen haben sollen.

Dieses Skript berücksichtigt, dass die ersetzten Links dieselben Namen haben sollten, die sie als Links hatten.

for link in `find . -type l`
do 
  target=`\ls -ld $link | sed 's/^.* -> \(.*\)/\1/'`
  test -e "$target" && (rm "$link"; cp "$target" "$link")
done

Wenn die Dateien den gleichen Namen wie das Ziel haben sollen, sollte dies ausreichen.

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

verwandte Informationen