2010-11-29 33 views
0

Je sais que c'est probablement élémentaire pour unix, mais je n'ai pas trouvé de réponse directe en ligne.Comment consolider les fichiers sélectionnés à partir de plusieurs sous-répertoires dans un répertoire

J'ai un répertoire avec des sous-répertoires. Certains de ces sous-répertoires contiennent des fichiers .mov. Je veux consolider tous les movs dans un seul répertoire. Je n'ai pas besoin de m'inquiéter des conflits de noms de fichiers car les fichiers proviennent d'un appareil photo numérique et il nomme les fichiers de façon incrémentielle, mais les divise en dossiers quotidiens.

Quel est le Unix-fu pour saisir tous ces fichiers et les copier (ou mieux encore, les déplacer) dans un répertoire de mon dossier personnel?

Merci.

Répondre

0
mv `find . -name "*.mov" | xargs` OUTPUTDIR/ 

Mise à jour après le commentaire de thkala:

find . -iname "*.mov" | while read line; do mv "$line" OUTPUTDIR/; done 
+0

Est-ce que cela ne casse pas si les fichiers ont des espaces dans leurs noms? Ou s'il y en a trop? Bien qu'il résout le problème de chevauchement de répertoire de ma réponse ... – thkala

+0

@thkala, oui, c'est le cas, voir la mise à jour – khachik

+0

Merci! Votre suggestion finale (trouver. -iname "* .mov" | en ligne de lecture, faire cp "$ line" OUTPUT_DIR /; done) a parfaitement fonctionné. C'est aussi le plus compréhensible pour moi, l'utilisateur unix non-expert. J'ai essayé de comprendre les solutions xargs, et j'ai lu sur xargs, mais je ne comprends toujours pas comment cette commande fonctionne. – beibei2

1

Que pensez-vous de cela?

find "$SOURCE_DIRECTORY" -type f -name '*.mov' -exec mv '{}' "$TARGET_DIRECTORY" ';' 

Si les répertoires source et cible ne se chevauchent pas, cela devrait fonctionner correctement.

EDIT:

BTW, si vous avez des extensions mixtes cas (x.mov, y.Mov, Z.MOV) comme cela est le cas avec de nombreux appareils photo, ce serait mieux. Il utilise -iname qui est insensible à la casse lors de la recherche:

find "$SOURCE_DIRECTORY" -type f -iname '*.mov' -exec mv '{}' "$TARGET_DIRECTORY" ';' 

Assurez-vous de remplacer le répertoire_source de $ et target_directory variables $ avec les répertoires réels et qu'ils ne se chevauchent pas (la cible étant quelque part sous la source)

EDIT 2:

PS: Je viens de remarquer que Khachik attrapé celui-ci avec son édition

+0

@thkala Je ne sais pas pourquoi, mais le code ne fonctionne pas, ou supprime les fichiers "* .mov" ... – khachik

+0

@khachik Vous avez remplacé $ SOURCE_DIRECTORY et $ TARGETDIRECTORY par vos chemins actuels, n'est-ce pas? Parce que ça marche très bien ici ... – thkala

+0

@thkala SureL 'trouver. -type f .... "OUT /" ';' 'OUT est un répertoire existant. – khachik

0

Si vous avez besoin pour faire face aux noms de fichiers étranges (espaces, caractères spéciaux), essayez ceci:

$ cd <source parent directory> 
$ find -name '*.mov' -print0 | xargs -0 echo mv -v -t <target directory> 

Retirez le « echo » ci-dessus pour faire réellement le mouvement , plutôt que d'imprimer ce qui se passerait. "Mv -v" donne une sortie verbeuse, "mv -t ..." spécifie le répertoire cible (peut-être spécifique à GNU)

"-print0" et "-0" sont des extensions pour gérer des noms de fichiers bizarres. Sur les systèmes non-GNU, vous devrez peut-être supprimer ces options, ce qui se traduira par des données séparées par un saut de ligne. Cela fonctionnera toujours sur les noms de fichiers avec des espaces, mais pas sur les noms de fichiers avec des retours à la ligne (oui, c'est possible).

+0

Je pense que xargs sans le -0 séparera les arguments à chaque espace plutôt que juste le retour à la ligne. Au moins le mien est comme ça ... – thkala