Comment puis-je copier un fichier et créer les répertoires cibles en même temps?

20

Je veux cp aaa/deep/sea/blob.psdàbbb/deep/sea/blob.psd

Comment faire la copie si les répertoires deepet sean'existent pas sous bbbafin que la copie crée à la fois les répertoires nécessaires et copie le fichier?

En ce moment, je deviens
No such file or directoryaussi profond et la mer n'existe pas.

J'ai regardé à travers les pages d'aide de l'homme et d'autres questions, mais rien ne me saute aux yeux.

Le plus proche que j'utilise utilise rcppour le répertoire:

rcp -r aaa/deep/sea/ bbb/deep/sea/

bien que cela copie tout le répertoire et le contenu et je veux juste le seul fichier. Essayer de faire cela a cependant donnécp: cannot create regular file bbb/deep/sea/blob.psd' such file or directory

Michael Durrant
la source

Réponses:

19

Essayez d'utiliser une telle fonction suivante pour une telle situation:

copy_wdir() { mkdir -p -- "$(dirname -- "$2")" && cp -- "$1" "$2" ; }

et l'utiliser comme

copy_wdir aaa/deep/sea/blob.psd bbb/deep/sea/blob.psd

Soit dit en passant, GNU cpa une --parentsoption. C'est vraiment proche de ce que vous voulez, mais pas exactement.
Il créera également un aaarépertoire dont vous n'avez pas besoin. Cependant, vous pouvez d'abord aaacopier et copier comme:

cd aaa && cp --parents deep/sea/blob.psd ../bbb/
se ruer
la source
24

Il est facile d'utiliser le installprogramme des coreutils qui est généralement utilisé à cet effet par des systèmes de construction comme automake :

install -D /path/to/source /path/to/destination

Notez que installcrée toutes les parties du chemin comme le mkdir -pfait, voyez man install. Je suis curieux de savoir pourquoi vous n'avez pas indiqué pourquoi vous voulez faire cela. Appeler mkdiret cpest très facile.

Pavel Šimerda
la source
2
Je pense qu'il y a beaucoup de bonnes réponses sur cette question, mais celle-ci obtient mon vote car c'est la plus portable. La rsyncréponse ne créera qu'un seul répertoire et paxne semble pas être courante.
Patrick
Utilisez -dplutôt que -Dsur un Mac.
Matt M.
notez que cette commande crée les fichiers de destination avec les autorisations 755( rwxr-xr-x), ce qui n'est probablement pas souhaité. vous pouvez spécifier autre chose avec le -mcommutateur, mais je n'ai pas pu trouver un moyen de simplement conserver les autorisations de fichier :(
törzsmókus
6

Avec les commandes standard (POSIX / Unix), vous avez:

pax -rws ':^:dest/dir/:' file .
Stéphane Chazelas
la source
1
Intéressant. Je n'avais jamais entendu parler de pax auparavant. Bien que j'aime son concept. Malheureusement, même s'il est dans POSIX, il semble que très peu de distributions l'installent par défaut :-(
Patrick
@Patrick - si vous sautez jusqu'à la fin de info tar- quelque part dans la section concernant la portabilité - je pense que vous constaterez que GNU tarprétend être entièrement paxcompatible. Je l'ai fait de toute façon, même si je n'ai jamais encore mis à l'épreuve ces affirmations.
mikeserv
5

Je ne connais pas de façon de le faire en utilisant cp, mais il est certainement possible d'utiliser rsync:

$ rsync sourcefile dir/

direst un répertoire qui ne doit pas exister. Il existe de nombreuses autres façons d'obtenir le même résultat à l'aide d'autres commandes.

mjturner
la source
3
Vous devez rsync -Rconserver le répertoire
heirarchy
@glennjackman En effet, l'utilisation «correcte» des rsyncbesoins nécessite plus d'options, mais la question portait simplement sur la création d'un répertoire cible inexistant, d'où ma brève réponse :)
mjturner
1
Au moins, GNU cpa l' --parentsoption.
peterph
2
@peterph En effet, mais vous êtes limité dans la dénomination du répertoire cible
mjturner
4
cd aaa
pax -rw deep/sea/blob.psd ../bbb

Si vous n'en avez pas pax(c'est mandaté par POSIX, en remplacement standard de cpio et tar qui avait trop d'incompatibilités à standardiser), utilisez cpio -pou à la tar -cf - … | tar -xf -place.

Gilles 'SO- arrête d'être méchant'
la source