Was ist der effizienteste Weg, um eine große Anzahl von Dateien zu verschieben, die sich in einem einzigen Verzeichnis befinden?

11

CentOS 5.x.

Ich entschuldige mich, wenn dies eine Wiederholungsfrage ist. Ich habe viele ähnliche Fragen gesehen (bezüglich des Löschens von Dateien), aber nicht genau das gleiche Szenario.

Ich habe ein Verzeichnis mit Hunderttausenden von Dateien (möglicherweise über eine Million) und als kurzfristige Lösung für ein anderes Problem muss ich diese Dateien an einen anderen Speicherort verschieben.

Nehmen wir zum Zwecke der Diskussion an, dass sich diese Dateien ursprünglich befinden /home/foo/bulk/und ich sie verschieben möchte/home/foo2/bulk2/

Wenn ich es versuche, mv /home/foo/bulk/* /home/foo2/bulk2/ erhalte ich den Fehler "zu viele Argumente".

Herr Google sagt mir, dass eine Alternative zum Löschen von Dateien in großen Mengen darin besteht, find auszuführen. Etwas wie: find . -name "*.pdf" -maxdepth 1 -print0 | xargs -0 rm

Das wäre in Ordnung, wenn ich etwas löschen würde, aber in diesem Fall möchte ich die Dateien verschieben ... Wenn ich so etwas wie find . -name "*" -maxdepth 1 -print0 | xargs -0 mv /home/foo2/bulk2/bash eingebe, beschwert ich mich darüber, dass die Datei kein Verzeichnis ist.

Was ist der beste Befehl, um die Dateien in großen Mengen von einem Verzeichnis in ein anderes zu verschieben?

Mike B.
quelle

Antworten:

16

Nutzen Sie die Option von GNU mv, -tum das Zielverzeichnis anzugeben, anstatt sich auf das letzte Argument zu verlassen:

find . -name "*" -maxdepth 1 -exec mv -t /home/foo2/bulk2 {} +

Wenn Sie sich auf einem System ohne diese Option befinden, können Sie eine Zwischenshell verwenden, um die Argumente in der richtigen Reihenfolge abzurufen ( find … -exec … +es wird nicht unterstützt, zusätzliche Argumente nach der Liste der Dateien einzufügen).

find . -name "*" -maxdepth 1 -exec sh -c 'mv "$@" "$0"' /home/foo2/bulk2 {} +
Gilles 'SO - hör auf böse zu sein'
quelle
Sie können find ... -exec sh -c 'blah "$ @" blah' sh {} + "(der" Shell-Trick ") verwenden, um Probleme im Zusammenhang mit der Reihenfolge von Argumenten zu lösen. Es gibt mehrere Beispiele dafür in den findutils ( info) Dokumentation, Suche nach "sh-c".
James Youngman
5

Betrachten mvSie das übergeordnete Verzeichnis anstelle der Dateien:

mv /home/foo/bulk /home/foo2/bulk2 && mkdir /home/foo/bulk

(Aber es kann Probleme verursachen, wenn /home/foo/bulkes in jedem Moment existieren muss.)

Scott
quelle
1
Ich würde dem hinzufügen, falls Ihr Zielverzeichnis existiert, verschieben Sie die Dateien im Zielverzeichnis in Ihr Quellverzeichnis (das große) und benennen Sie das Verzeichnis um.
Sbenitezb
Danke - toller Vorschlag. In diesem Fall muss das Verzeichnis zu jedem Zeitpunkt vorhanden sein. Tolle Idee.
Mike B
Ich muss zugeben, dass ich nicht verstehe, was diese Antwort bewirkt. Warum mkdir? Und was ist mit dem Dir, das in jedem Moment existiert oder nicht? Warum sollte dies die Dinge beschleunigen?
Monica Heddneck
Ich weiß, dass dieser Kommentar ein Jahr alt ist, aber der letzte war fünf Jahre alt, also dachte ich mir, ich könnte genauso gut antworten ... Ihre ersten beiden Fragen sind korreliert. Dies mkdirliegt daran, dass der gesamte Ordner und alles darin in das andere Verzeichnis verschoben wird und nicht mehr im alten Verzeichnis vorhanden ist. Es stellt sicher, dass das alte Verzeichnis noch vorhanden ist. Dies würde jedoch nicht ausreichen, wenn ständig ein Dienst ausgeführt würde, der von dem ersten Verzeichnis abhängt, das immer vorhanden ist, da er verschoben und dann neu erstellt wird. Es macht nichts schneller, nur einfacher, indem es weniger Argumente liefert.
Lucas Leblanc
0

Nur aus Gründen der Abwechslung verwende ich in einigen Fällen gern cpio.

find tmp |cpio -v  -p --make-directories --sparse tmp2
Arthur Ulfeldt
quelle
1
Wenn sich Quelle und Ziel im selben Dateisystem befinden, kann dieser Ansatz sehr ineffizient sein (unnötiges Kopieren). Auch ist es immer besser zu verwenden -print0und -0Optionen.
Pabouk
0

Mit GNU mv:

find . -mindepth 1 -exec mv -t /tmp {} +

Auf Systemen wie OS X, die nicht haben, mv -taber haben -print0und xargs -0:

find . -mindepth 1 -print0|xargs -0 -I, mv , /tmp

Oder wenn die Dateinamen keine Leerzeichen, Anführungszeichen, Backslashes oder Newlines (mit OS X xargs) oder Anführungszeichen, Backslashes oder Newlines (mit GNU xargs) enthalten:

ls|xargs -I, mv , /tmp
Lri
quelle
-3

Versuchen Sie für eine bestimmte Zeit Folgendes:

find . -name "*" -type f -mtime +7 -exec mv -t /folder/to/transfer/files {} +
Jean
quelle