web-dev-qa-db-fra.com

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

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

Fol1/Fol2
Fol3
Fol4/Fol5

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

53
InquilineKea

Accédez au répertoire de niveau supérieur 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 dans zsh. Si votre Shell est bash, vous devrez exécuter shopt -s globstar d'abord (vous pouvez et devez mettre cette commande dans votre ~/.bashrc). Si votre Shell est ksh, vous devrez exécuter set -o globstar d'abord (mettez-le dans votre ~/.kshrc).

Alternativement, utilisez find, qui fonctionne partout sans préparation spéciale mais est plus compliqué:

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

Si vous souhaitez supprimer les répertoires vides par la suite, dans zsh:

rmdir **/*(/^Fod)

En bash ou ksh:

rmdir **/*/

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

find . -depth -type d -empty -exec rmdir {} \;

Si vous souhaitez uniquement déplacer le .Zip fichiers, vous pourriez faire quelque chose comme

mkdir ./zipfiles
find . -name "*.Zip" -exec mv "{}" ./zipfiles \;
15
Bernhard

Si vous utilisez bash version 4 ou supérieure ou zsh vous pouvez également utiliser la globalisation récursive:

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

Cela déplacera UNIQUEMENT les fichiers et non leurs chemins d'accès relatifs, de sorte que des collisions pourraient se produire.

3
SuperMagic

Celui-ci est sûr lors du déplacement de données et sans erreur, ce qui supportait la plupart des distributions, quelles que soient les versions. Cette commande analyse les sous-répertoires, puis les déplace ou les copie dans votre nouveau répertoire de destination.

find . -name *.flac -exec mv '{}' "./flac/" ";"
  • Exécutez cette commande dans le répertoire principal qui contient des sous-répertoires avec les fichiers que vous souhaitez déplacer.
  • Où vous pouvez changer *.flac à quelque chose comme *.Zip dans ton cas. Ou *.doc n'importe quelle extension fonctionne.
  • et mv est la commande pour déplacer des fichiers, ou vous pouvez utiliser cp pour copier des données au lieu de les déplacer.
  • ./flac/ est le répertoire de destination dans lequel je souhaite déplacer tous les fichiers FLAC. Vous pouvez également lui donner un chemin complet comme /home/myid/flac/

Exemple complet. (dans ce cas, il existe de nombreux sous-répertoires avec le nom de l'artiste musical à /home/myid/Music/, puis les fichiers FLAC se trouvent à différents niveaux de sous-répertoires. Étant donné que je n'ai pas besoin de dossiers d'artistes mais que je souhaite avoir tous les fichiers FLAC dans un seul répertoire à /home/myid/Music/flac/

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

Ensuite, il affichera tous les fichiers FLAC.

2
Seandex

En supposant que vous disposez des versions GNU de find et mv, les éléments suivants seront plus efficaces que les réponses basées sur la recherche existantes:

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

Utilisant un + à la fin de la recherche -exec signifie qu'une liste de fichiers sera transmise à la commande mv, plutôt que d'exécuter une commande mv par fichier trouvé. Cependant, une limitation de ceci est que vous ne pouvez placer le '{}' qu'à la fin de la commande, ce qui nécessite l'utilisation de l'option mv --target-directory, et autant que je sache, c'est un GNU-isme.

0
evilsoup

En tant que hack bash, vous pouvez utiliser la puissance 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 a l'avantage de ne pas dépendre des extensions de fichiers, car il utilise la commande file pour choisir les fichiers à déplacer et préserve la structure du répertoire, mais il ne fonctionne pas avec les chemins d'accès contenant des espaces.

Le dernier rm est là juste pour supprimer les fichiers originaux (parce que @InquilineKea dit qu'il ne se soucie pas du dossier d'origine dans le commentaire).

Bien sûr, cela est particulièrement approprié 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 nommage, au lieu du contenu de file).

0
Giacomo Tesio