Verschieben Sie alle Dateien mit einer bestimmten Erweiterung aus mehreren Unterverzeichnissen in ein Verzeichnis

42

Ich habe eine Reihe von .zip-Dateien in mehreren Verzeichnissen:

Fol1/Fol2
Fol3
Fol4/Fol5

Wie würde ich sie alle in einen gemeinsamen Basisordner verschieben?

InquilineKea
quelle
Möchten Sie die Verzeichnisstruktur beibehalten? Sie möchten die Verzeichnisse oder nur die ZIP-Dateien verschieben?
Jordanien
Ich möchte nur die ZIP-Dateien verschieben. Die Verzeichnisse interessieren mich nicht wirklich - sie können alleine gelassen oder gelöscht werden.
InquilineKea

Antworten:

54

Wechseln Sie in das oberste Verzeichnis des Baums, der die ZIP-Dateien enthält ( cd …), und führen Sie es aus

mv **/*.zip /path/to/single/target/directory

Dies funktioniert in zsh sofort. Wenn Ihre Shell bash ist, müssen Sie shopt -s globstarzuerst ausführen (Sie können und sollten diesen Befehl in Ihre einfügen ~/.bashrc). Wenn Ihre Shell ksh ist, müssen Sie set -o globstarzuerst ausführen (in Ihre einfügen ~/.kshrc).

Alternativ kann verwendet werden find, was überall ohne besondere Vorbereitung funktioniert, aber komplizierter ist:

find . -name '*.zip' -exec mv {} /path/to/single/target/directory \;

Wenn Sie anschließend leere Verzeichnisse entfernen möchten, gehen Sie in zsh wie folgt vor:

rmdir **/*(/^Fod)

In bash oder ksh:

rmdir **/*/

und wiederholen, solange leere Verzeichnisse entfernt werden müssen. Alternativ in einer beliebigen Schale

find . -depth -type d -empty -exec rmdir {} \;
Gilles 'SO - hör auf böse zu sein'
quelle
Der erste findobige Befehl funktionierte in bash, musste aber zu find . -nameetc wechseln , damit es funktioniert.
JeffThompson
1
@ Jeff .ist implizit für GNU find, aber nicht für andere, ich habe es explizit hinzugefügt.
Gilles 'SO- hör auf böse zu sein'
13

Wenn Sie nur die .zipDateien verschieben möchten, können Sie so etwas tun

mkdir ./zipfiles
find . -name "*.zip" -exec mv "{}" ./zipfiles \;
Bernhard
quelle
3

Wenn Sie bash Version 4 oder höher oder zsh verwenden , können Sie auch rekursives Globbing verwenden:

mv **/*.zip /path/to/move/zip/files/to

Dadurch werden NUR die Dateien und nicht ihre relativen Pfade verschoben, sodass möglicherweise Kollisionen auftreten.

SuperMagic
quelle
Was meinst du mit relativen Pfaden?
Kunok
2

Dieser ist sicher beim Verschieben von Daten und fehlerfrei, was vor allem Distribution unabhängig von Versionen unterstützt. Dieser Befehl durchsucht Unterverzeichnisse und verschiebt oder kopiert sie in Ihr neues Zielverzeichnis.

find . -name *.flac -exec mv '{}' "./flac/" ";"
  • Führen Sie diesen Befehl im Hauptverzeichnis aus, das Unterverzeichnisse mit den zu verschiebenden Dateien enthält.
  • Wo können Sie *.flacin etwas wie *.zipin Ihrem Fall ändern . Oder *.doceinfach jede Erweiterung funktioniert.
  • und mvist der Befehl zum Verschieben von Dateien, oder Sie können cpDaten kopieren, anstatt sie zu verschieben.
  • ./flac/ist das Zielverzeichnis, in das ich alle FLAC-Dateien verschieben möchte. Sie können ihm auch einen vollständigen Pfad geben/home/myid/flac/

Vollständiges Beispiel. (In diesem Fall gibt es viele Unterverzeichnisse mit dem Namen des Musikkünstlers unter /home/myid/Music/und dann sind die FLAC-Dateien über alle Unterverzeichnisse verteilt. Da ich keine Künstlerordner benötige, sondern alle FLAC-Dateien in einem Verzeichnis unter haben möchte/home/myid/Music/flac/

cd /home/myid/Music
mkdir flac
find . -name *.flac -exec mv '{}' "./flac/" ";"
cd flac
ls

Dann werden alle FLAC-Dateien angezeigt.

Seandex
quelle
Was bedeutet ;tun?
Francesco Boi
@FrancescoBoi Es muss gewartet werden, bis der Bash-Befehl in derselben Zeile seinen Job beendet hat. Fahren Sie dann mit der nächsten Zeile der Bash-Befehle fort. Dies ist nützlich für Befehle, die Skripte wie .pl oder Python enthalten, da bash diese einfach ausführt und dann in die nächste Zeile springt. Nach den Befehlen, die Zeit oder ein Skript benötigen, überspringt Bash es.
Seandex
0

Als Bash-Hack können Sie die folgenden Möglichkeiten nutzen tar:

(cd origin/;find . -exec file --mime-type "{}" \;|grep "application/zip"|cut -d ':' -f 1|xargs tar cf -)|(cd target/; tar xf -) && rm -fr origin/

Dies hat den Vorteil, dass es nicht von Dateierweiterungen abhängt, da es den fileBefehl zum Auswählen der zu verschiebenden Dateien verwendet und die Verzeichnisstruktur beibehält, aber nicht mit Pfaden arbeitet, die Leerzeichen enthalten.

Das Finale rmdient nur zum Entfernen der Originaldateien (da @InquilineKea mitteilt, dass ihm der Originalordner im Kommentar egal ist).

Dies ist natürlich besonders geeignet, wenn sich der Ursprungs- / und der Zielordner / auf unterschiedlichen Datenträgern befinden. Andernfalls sind die anderen vorgeschlagenen Lösungen effizienter (auch wenn sie auf Namenskonventionen anstatt auf deren fileInhalten beruhen ).

Giacomo Tesio
quelle
0

Vorausgesetzt, Sie haben die GNU-Versionen von find und mv, ist Folgendes effizienter als die vorhandenen findbasierten Antworten:

find . -name '*.zip' -exec mv --target-directory='/path/to/outputdir' '{}' +

Die Verwendung von a +am Ende des Befehls find -exec bedeutet, dass eine Liste von Dateien an den Befehl mv übergeben wird, anstatt einen Befehl mv pro gefundener Datei auszuführen. Eine Einschränkung ist jedoch, dass Sie nur das '{}' am Ende des Befehls einfügen können, was die Verwendung der Option mv --target-directory erforderlich macht, und soweit ich weiß, handelt es sich um einen GNU-Ismus.

Übelsuppe
quelle