Verschieben Sie eine Datei und hinterlassen Sie einen Softlink

10

Ich suche nach einem einzelnen Linux-Befehl, mit dem ich das Gleiche tun kann:

cp /some/path/file /another/path/ && ln -sf /another/path/file /some/path/

Wenn es keine gibt, wie geht das am besten für eine Reihe von Dateien?

itsadok
quelle
Ich kenne Bash-Skripte nicht gut genug, um sie zu schreiben, aber meine Lösung wäre, einfach ein Skript zu schreiben und es als etwas eingängiges wie cpln zu bezeichnen
Unkwntech
1
Sollte cp nicht mv sein?
Bart van Heukelom
Nein. Die Option -f für ln kümmert sich darum.
InnaM
1
versuchen Sie es auf einer 10 GB-Datei
Hayalci
2
@HelloGoodbye Sie verwechseln &&mit &. Wie geschrieben, überprüft die Zeile den Rückgabewert von cp und führt den zweiten Teil nur aus, wenn dies erfolgreich war.
Itsadok

Antworten:

7

Ein kleiner Hinweis ist, dass Sie ln beide Male verwenden können, damit der Befehl die Daten nicht tatsächlich verschiebt (vorausgesetzt, beide Pfade befinden sich im selben Dateisystem).

ln /some/path/file /another/path/ && ln -sf /another/path/file /some/path/

Ich gehe jedoch davon aus, dass Sie den Inhalt von / some / path / auf eine andere Festplatte verschieben und dann Links zu den neuen Dateien erstellen möchten, damit "niemand" dies bemerkt.

for f in `ls /some/path/`; do ln /some/path/$f /another/path/ && ln -sf /another/path/$f /some/path; done

Wickeln Sie es in eine Bash-Funktion:

function cpln {
    for f in `ls $1`
    do
        ln $1/$f $2 && ln -sf $2/$f $1
    done
}
Herr Hai
quelle
Gibt es eine Möglichkeit, dies zum Laufen zu bringen, wenn das, was ich bewege, zufällig ein Verzeichnis ist?
Tladuke
Wie verschiebt dies die eigentliche Datei auf der Festplatte?
Ibrahim
Ibrahim: Die Daten bewegen sich nicht, sondern aktualisieren nur die Zeiger im Verzeichnis.
Herr Shark
tladuke: Ja und nein. Da das Verzeichnis auf der Festplatte viel kleiner ist, ist der ln-Trick (der für Regisseure nicht funktioniert) nicht erforderlich. Machen Sie einfach einen mv :-)
Mr Shark
2

Theres mein Skript, das Sie verwenden könnten (nimmt zwei Parameter / einige / Pfad / Datei und / andere / Pfad /):

#!/bin/bash
cp $1 $2
if [ "$?" -ne "0" ]; then
    echo "Some error"
    exit 1
    fi
ln -sf $2/${1##*/} ${1%/*}
Kazimieras Aliulis
quelle
Cooler Trick mit den Saitenmanipulationen, das habe ich noch nie gesehen. Vielen Dank!
itsadok
1

Im Ernst, ich dachte, das wäre eine wirklich einfache Frage.

Folgendes kann ich in Perl tun:

#!/bin/perl
# Usage: cpln TARGETDIR SOURCE...
# Example: find tree/ -type f | xargs cpln commands/

$target = shift;

foreach(@ARGV) {
    m[(.*)/([^/]+)];
    system("cp $_ $target");
    system("ln -sf $target/$2 $1/");
}

Ich hatte auf etwas Eleganteres gehofft, aber ich denke, ich werde das nutzen.

itsadok
quelle
1
Um dies "in Perl" zu tun, sollten Sie File :: Copy (oder ähnliches) und symlink () verwenden. Perl ist keine Muschel; Vermeiden Sie system () und insbesondere die Übergabe ganzer Befehlszeilen an system () (z. B. was ist, wenn ein Argument ein Leerzeichen enthält?). So oder so, immer, immer, überprüfen Sie IMMER die Rückgabewerte.
John Siracusa