web-dev-qa-db-fra.com

Copier 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 (tous les fichiers doivent donc se trouver dans/répertoire_cible /).

  • Il ne copie pas les fichiers avec des espaces dans les noms de fichiers (qui sont assez nombreux)

Des solutions à ces problèmes?

90
Abdel

--parents copie la structure de répertoires, vous devriez donc vous en débarrasser.

Comme vous l'avez écrit, la find est exécutée et le résultat est placé sur la ligne de commande de sorte que cp ne puisse pas distinguer les espaces séparant les noms de fichiers et les espaces dans le nom du fichier. Il vaut mieux faire quelque chose comme

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

dans lequel cp est exécuté pour chaque nom de fichier trouvé par find et transmis correctement. Voici plus d'informations sur cette technique.

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

$ cp **/*.xls target_directory

zsh peut étendre les caractères génériques pour inclure des sous-répertoires et rend ce type de tâche très facile.

141
Brian Agnew

De tout ce qui précède, je suis venu avec 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 en cours 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 - conserve les attributs du fichier
  • r - récursif
  • v - verbose (vous montre ce qui est copié)
27
guya

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

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

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

8
stingMantis

Je devais aussi le faire moi-même. Je l'ai fait via l'argument --parents de cp:

find SOURCEPATH -name filename*.txt -exec cp --parents {} DESTPATH \;
3
That Guy
find [SOURCEPATH] -type f -name '[PATTERN]' | 
    while read P; do cp --parents "$P" [DEST]; done

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

1
Camion