171 votes

Copie tous les fichiers avec une certaine extension de tous les sous-répertoires.

Sous unix, je veux copier tous les fichiers avec une certaine extension (tous les fichiers excel) de tous les sous-répertoires vers un autre répertoire. J'ai la commande suivante :

cp --parents `find -name \*.xls*` /target_directory/

Les problèmes avec cette commande sont :

  • Il copie également la structure du répertoire, et je ne veux que les fichiers (donc tous les fichiers doivent se retrouver dans le répertoire /target_directory/).

  • Il ne copie pas les fichiers dont le nom contient des espaces (ce qui est assez fréquent).

Des solutions à ces problèmes ?

259voto

Brian Agnew Points 143181

--parents copie la structure du répertoire, donc vous devriez vous en débarrasser.

La façon dont tu as écrit ça, le find s'exécute, et la sortie est mise sur la ligne de commande de telle sorte que cp ne peut pas faire la distinction entre les espaces séparant les noms de fichiers, et les espaces sur le nom du fichier. Il est préférable de faire quelque chose comme

$ find . -name \*.xls -exec cp {} newDir \;

dans laquelle cp est exécuté pour chaque nom de fichier que find trouve, et passe le nom du fichier correctement. Voici plus d'informations sur cette technique.

Au lieu de tout ce qui précède, vous pourriez utiliser zsh et tapez simplement

$ cp **/*.xls target_directory

zsh peut étendre les caractères génériques pour inclure les sous-répertoires et rendre ce genre de chose très facile.

52voto

guya Points 601

De tout ce qui précède, je suis arrivé à cette version. Cette version fonctionne également pour moi dans le terminal de récupération Mac.

find ./ -name '*.xsl' -exec cp -prv '{}' '/path/to/targetDir/' ';'

Il cherchera dans le répertoire actuel et récursivement dans tous les sous-répertoires les fichiers portant l'extension xsl. Il les copiera tous dans le répertoire cible.

Les drapeaux cp sont :

  • p - préserver les attributs du fichier
  • r - récursif
  • v - verbeux (vous montre tout ce qui se passe) ce qui est copié)

12voto

stingMantis Points 175

J'ai eu un problème similaire. Je l'ai résolu en utilisant :

find dir_name '*.mp3' -exec cp -vuni '{}' "../dest_dir" ";"

El '{}' et ";" exécute la copie sur chaque fichier.

6voto

That Guy Points 61

J'ai également dû le faire moi-même. Je l'ai fait via l'argument --parents de cp :

find SOURCEPATH -name filename*.txt -exec cp --parents {} DESTPATH \;

2voto

Camion Points 371
find [SOURCEPATH] -type f -name '[PATTERN]' | 
    while read P; do cp --parents "$P" [DEST]; done

vous pouvez supprimer le --parents mais il y a un risque de collision si plusieurs fichiers portent le même nom.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X