100 votes

Bash : Copie récursive de fichiers nommés, en préservant la structure des dossiers

J'espérais :

cp -R src/prog.js images/icon.jpg /tmp/package

donnerait une structure symétrique dans la direction de destination :

/tmp
|
+-- package
    |
    +-- src
    |   |
    |   +-- prog.js
    |
    +-- images
        |
        +-- icon.jpg

mais à la place, les deux fichiers sont copiés dans /tmp/package. Une copie à plat. (Ceci est sous OSX).

Existe-t-il une fonction bash simple que je peux utiliser pour copier tous les fichiers, y compris les fichiers spécifiés par un caractère de remplacement (par exemple src/*.js), à leur place dans le répertoire de destination ? Un peu comme "pour chaque fichier, exécuter mkdir -p $(dirname "$file"); cp "$file" $(dirname "$file") ", mais peut-être une seule commande.

Il s'agit d'un fil de discussion pertinent, qui suggère que ce n'est pas possible. La solution de l'auteur ne m'est cependant pas très utile, car je voudrais simplement fournir une liste de fichiers, avec ou sans caractère de remplacement, et qu'ils soient tous copiés dans le répertoire de destination. IIRC MS-DOS xcopy fait cela, mais il ne semble pas y avoir d'équivalent pour cp.

151voto

ustun Points 2918

Avez-vous essayé d'utiliser l'option --parents ? Je ne sais pas si OS X supporte cela, mais cela fonctionne sous Linux.

cp --parents src/prog.js images/icon.jpg /tmp/package

Si cela ne fonctionne pas sur OS X, essayez de

rsync -R src/prog.js images/icon.jpg /tmp/package

comme aif l'a suggéré.

22voto

Randy Proctor Points 2331

Un moyen :

tar cf - <files> | (cd /dest; tar xf -)

18voto

Jonathan Leffler Points 299946

Sinon, si vous êtes de la vieille école, utilisez cpio :

cd /source;
find . -print | cpio -pvdmB /target

En clair, vous pouvez filtrer la liste des fichiers à votre guise.

L'option '-p' est pour le mode 'pass-through' (contrairement à '-i' pour l'entrée ou '-o' pour la sortie). L'option '-v' est verbeuse (liste les fichiers au fur et à mesure qu'ils sont traités). L'option '-m' préserve les temps de modification. Le '-B' signifie utiliser des 'big blocks' (où les big blocks sont de 5120 octets au lieu de 512 octets) ; il est possible que cela n'ait aucun effet de nos jours.

16voto

Ryan Bright Points 2593

l'option -R de rsync fera ce que vous attendez. C'est un copieur de fichiers très riche en fonctionnalités. Par exemple :

$ rsync -Rv src/prog.js images/icon.jpg /tmp/package/
images/
images/icon.jpg
src/
src/prog.js

sent 197 bytes  received 76 bytes  546.00 bytes/sec
total size is 0  speedup is 0.00

Résultats de l'échantillon :

$ find /tmp/package
/tmp/package
/tmp/package/images
/tmp/package/images/icon.jpg
/tmp/package/src
/tmp/package/src/prog.js

2voto

Aif Points 4603

Rsync bien sûr ! tutoriel ici. et ici

Ou unisson

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