Déplacez tous les fichiers avec une certaine extension de plusieurs sous-répertoires dans un seul répertoire

43

J'ai un tas de fichiers .zip dans plusieurs répertoires:

Fol1/Fol2
Fol3
Fol4/Fol5

Comment pourrais-je les déplacer tous vers un dossier de base commun?

InquilineKea
la source
Voulez-vous conserver la structure de répertoires? Vous voulez déplacer les répertoires, ou juste les fichiers zip?
Jordanie
Je veux juste déplacer les fichiers zip. Je ne me soucie pas vraiment des répertoires - ils peuvent être laissés seuls ou supprimés.
InquilineKea

Réponses:

55

Allez dans le répertoire toplevel de l’arborescence contenant les fichiers zip ( cd …), puis exécutez

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

Cela fonctionne hors de la boîte en zsh. Si votre shell est bash, vous devrez d' shopt -s globstarabord l' exécuter (vous pouvez et devriez mettre cette commande dans votre ~/.bashrc). Si votre shell est en ksh, vous devrez d' set -o globstarabord l' exécuter (mettez-le dans votre ~/.kshrc).

Alternativement, utilisez findqui fonctionne partout sans préparation particulière mais qui est plus compliqué:

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

Si vous voulez ensuite supprimer les répertoires vides, en zsh:

rmdir **/*(/^Fod)

En bash ou en ksh:

rmdir **/*/

et répétez tant qu'il y a des répertoires vides à supprimer. Alternativement, dans n'importe quelle coquille

find . -depth -type d -empty -exec rmdir {} \;
Gilles, arrête de faire le mal
la source
La première findcommande ci-dessus a fonctionné sous bash, mais a dû être remplacée par find . -nameetc. pour que cela fonctionne.
JeffThompson
1
@Jeff .est implicite pour la recherche GNU mais pas pour les autres, je l'ai ajouté explicitement.
Gilles, arrête de faire le mal.
13

Si vous voulez seulement déplacer les .zipfichiers, vous pouvez faire quelque chose comme:

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

Si vous utilisez bash version 4 ou supérieure ou zsh, vous pouvez également utiliser la méthode de redimensionnement récursif:

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

Cela déplacera SEULEMENT les fichiers et non leurs chemins relatifs, ainsi des collisions pourraient se produire.

SuperMagic
la source
qu'entendez-vous par chemins relatifs?
Kunok
2

Celui-ci est sûr lorsque vous déplacez des données et sans erreur qui supportait la plupart des distributions indépendamment des versions. Cette commande va scanner les sous-répertoires puis les déplacer ou les copier dans votre nouveau répertoire de destination.

find . -name *.flac -exec mv '{}' "./flac/" ";"
  • Exécutez cette commande dans le répertoire principal qui contient les sous-répertoires avec les fichiers que vous souhaitez déplacer.
  • Où vous pouvez changer *.flacquelque chose comme *.zipdans votre cas. Ou *.doctout simplement une extension fonctionne.
  • Et mvest la commande pour déplacer des fichiers, ou vous pouvez utiliser cppour copier des données au lieu de déplacer.
  • ./flac/est le répertoire de destination vers lequel je veux déplacer tous les fichiers FLAC. Vous pouvez également lui donner un chemin complet comme/home/myid/flac/

Exemple complet. (Dans ce cas, il y a beaucoup de sous-répertoires avec le nom d'artiste de musique à /home/myid/Music/et les fichiers FLAC sont répartis sur différents niveaux de sous-répertoires. Comme je n'ai pas besoin de dossiers d'artistes, je veux que tous les fichiers FLAC soient dans un répertoire à/home/myid/Music/flac/

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

Ensuite, tous les fichiers FLAC seront affichés.

Seandex
la source
qu'est - ce que ;faire?
Francesco Boi
@FrancescoBoi s'assure d'attendre que la commande bash de la même ligne termine son travail. puis passez à la ligne suivante des commandes bash. Ceci est utile pour les commandes contenant des scripts tels que .pl ou python, car bash l’exécutera puis passera à la ligne suivante. Pour plus de sécurité, j’utilise; après les commandes qui prennent du temps ou un script, au cas où bash l'ignore.
Seandex
0

En tant que bash hack, vous pouvez utiliser le pouvoir de 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/

Cela présente l'avantage de ne pas dépendre des extensions de fichier, car elle utilise la filecommande pour choisir les fichiers à déplacer et préserve la structure des répertoires, mais elle ne fonctionne pas avec les chemins contenant des espaces.

La finale rmest juste là pour supprimer les fichiers originaux (car @ InquilineKea a dit qu'il ne se souciait pas du dossier original dans le commentaire).

Bien entendu, cela convient particulièrement si les dossiers origin / et target / se trouvent sur des disques différents. Sinon, les autres solutions proposées sont plus efficaces (même si elles reposent sur des conventions de dénomination plutôt que sur filele contenu).

Giacomo Tesio
la source
0

En supposant que vous ayez les versions GNU de find et mv, les solutions suivantes seront plus efficaces que les réponses existantes basées sur find:

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

L'utilisation de a +à la fin de find -exec signifie qu'une liste de fichiers sera transmise à la commande mv, au lieu d'exécuter une commande mv par fichier trouvé. Cependant, une limitation de ceci est que vous ne pouvez placer que le '{}' à la fin de la commande, ce qui nécessite l'utilisation de l'option mv --target-directory et, autant que je sache, il s'agit d'un GNU-ism.

vilsoup
la source