it-swarm.com.de

mv: Datei nur verschieben, wenn das Ziel nicht vorhanden ist

Kann ich benutzen mv file1 file2 so, dass es sich nur bewegt file1 bis file2 wenn file2 existiert nicht?

Ich habe es versucht

yes n | mv -i file1 file2

(Dadurch kann mv fragen, ob Datei2 überschrieben werden soll, und automatisch mit Nein antworten.) Aber neben dem Missbrauch von -i es gibt mir auch keine netten Fehlercodes (immer 141 statt 0, wenn verschoben und etwas anderes, wenn nicht verschoben)

51

mv -vn file1 file2. Dieser Befehl macht, was Sie wollen. Du kannst überspringen -v falls Sie es wollen.

-v macht es ausführlich - mv teilt Ihnen mit, dass die Datei verschoben wurde, wenn sie verschoben wurde (nützlich, da die Möglichkeit besteht, dass die Datei nicht verschoben wird).

-n wird nur verschoben, wenn Datei2 nicht vorhanden ist.

Bitte beachten Sie jedoch, dass dies ist nicht POSIX as von ThomasDickey erwähnt .

71
MatthewRock

mv -n

Von man mv auf einem GNU System:

-n, --no-clobber
Überschreiben Sie keine vorhandene Datei

Auf einem FreeBSD-System:

-n Überschreibe keine vorhandene Datei. (Die Option -n überschreibt alle vorherigen Optionen -f oder -i.)

17
Dani_l
if [ ! -e file2 ] && [ ! -L file2 ]
then
    mv file1 file2
# else echo >&2 there is already a file2 file.
fi

Oder:

if ! ls -d file2 > /dev/null 2>&1
then
    mv file1 file2
fi

Würde nur mv ausführen, wenn file2 existiert nicht. Beachten Sie, dass dies nicht garantiert, dass ein file2 wird nicht überschrieben, weil ein file2 könnte zwischen dem Test und dem mv erstellt worden sein, aber beachten Sie, dass mindestens aktuelle Versionen von GNU mv mit -i oder -n geben Sie diese Garantie auch nicht (obwohl die Rennbedingungen dort enger sind, da die Prüfung innerhalb von mv erfolgt).

Auf der anderen Seite ist es portabel, ermöglicht die Unterscheidung zwischen den Fällen und funktioniert unabhängig vom Typ des file2 Datei (regulär, Pipe, gerade Verzeichnis).

10
Majenko

Ein rennfreier Ansatz mit GNU ln vorausgesetzt file1 Ist nicht vom Typ Verzeichnis:

ln -PT file1 file2 && rm file1

(Mit Ausnahme von Fehlern in einigen Netzwerkdateisystemen) garantiert dies, dass keine file2 - Datei überschrieben wird (oder dass file2 Nicht verschoben wird, wenn file1 Vom Typ Verzeichnis ist hinein), weil der Systemaufruf link() im Gegensatz zum Systemaufruf rename() fehlschlägt, wenn das Ziel vorhanden ist.

Es wird jedoch einen Zwischenzustand geben, in dem die Datei sowohl als file1 Als auch als file2 Existiert.

Die Option -T (Um immer eine link("file1", "file2") auszuführen, auch wenn file2 Vom Typ Verzeichnis ist) ist GNU-spezifisch.

Sie können auch den Befehl link verwenden:

link file1 file2 && rm file1

Wenn jedoch file1 Abhängig von der Implementierung ein Symlink ist, ist file2 Entweder ein Hardlink zu diesem Symlink oder zum Ziel dieses Symlinks (verwenden Sie unter Solaris /usr/sbin/link). , nicht /usr/xpg4/bin/link).

8

Sie können auch test -e name Verwenden, das true zurückgibt, wenn der Name vorhanden ist (unabhängig von Datei, Verzeichnis oder Symlink).

Zum Beispiel:

touch file
mkdir dir
ln -s file symlink
test -e file && echo file exists
test -e dir && echo dir exists
test -e symlink && echo symlink exists
test -e file || echo you wont see this echo
test -e doesnotexist || echo doesnotexist does not exist...
0
H Briceno