Como posso copiar um arquivo e criar os diretórios de destino ao mesmo tempo?

20

Eu quero cp aaa/deep/sea/blob.psdabbb/deep/sea/blob.psd

Como faço a cópia se os diretórios deepe seanão existirem bbbpara que a cópia crie os diretórios necessários e copie o arquivo?

Agora eu chego
No such file or directorytão fundo e o mar não existe.

Eu olhei através do homem páginas de ajuda e outras perguntas, mas nada salta para mim.

O mais próximo que eu tenho está usando rcppara o diretório:

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

embora isso copie todo o diretório e conteúdo e eu apenas queira o único arquivo. Tentando fazer isso, no entanto, deucp: cannot create regular file bbb/deep/sea/blob.psd' such file or directory

Michael Durrant
fonte

Respostas:

19

Tente usar a próxima função para essa situação:

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

e use-o como

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

A propósito, o GNU cptem uma --parentsopção. É realmente perto do que você deseja, mas não exatamente.
Ele também criará um aaadiretório que parece que você não precisa. No entanto, você pode primeiro fazer o cd aaae copiar como:

cd aaa && cp --parents deep/sea/blob.psd ../bbb/
pressa
fonte
24

É fácil usar o installprograma a partir do coreutils, que normalmente é usado para esse fim por sistemas de compilação como o automake :

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

Observe que installcria todas as partes do caminho, assim como mkdir -pfaz, veja man install. Estou curioso para saber por que você não incluiu por que deseja fazer isso. Ligar mkdire cpé muito fácil.

Pavel Šimerda
fonte
2
Eu acho que há muitas respostas boas para essa pergunta, mas essa é a que mais me agrada. A rsyncresposta criará apenas 1 diretório e paxnão parece ser comum.
626 Patrick
Use em -dvez de -Dno Mac.
Matt M.
observe que este comando cria os arquivos de destino com permissões 755( rwxr-xr-x), o que provavelmente não é desejado. você pode especificar outra coisa com a -mopção, mas não consegui encontrar uma maneira de manter apenas as permissões de arquivo :(
törzsmókus
6

Com os comandos padrão (POSIX / Unix), você tem:

pax -rws ':^:dest/dir/:' file .
Stéphane Chazelas
fonte
11
Interessante. Eu nunca tinha ouvido falar de pax antes. Embora eu goste do seu conceito. Infelizmente, apesar de estar no POSIX, parece que poucas distros o instalam por padrão :-( #
Patrick
@ Patrick - se você pular todo o caminho até o final de info tar- em algum lugar da seção de preocupações com portabilidade - acho que você descobrirá que o GNU tarafirma ser totalmente paxcompatível. Eu fiz de qualquer maneira, embora eu ainda não tenha conseguido testar essas alegações.
mikeserv
5

Não conheço uma maneira de fazer isso usando cp, mas certamente é possível usar rsync:

$ rsync sourcefile dir/

onde diré um diretório que não precisa existir. Existem muitas outras maneiras de conseguir o mesmo usando outros comandos.

mjturner
fonte
3
Você precisa rsync -Rpara preservar a hierarquia de diretório
glenn jackman
@glennjackman Na verdade, o uso 'adequado' de rsyncnecessidades mais opções, mas a questão era simplesmente sobre a criação de um diretório de destino não existe, portanto, a minha resposta breve :)
mjturner
11
Pelo menos o GNU cptem a --parentsopção.
Peterph
2
@peterph fato, mas então você está restrito na nomeação do diretório de destino
mjturner
4
cd aaa
pax -rw deep/sea/blob.psd ../bbb

Se você não possui pax(é obrigatório pelo POSIX, como uma substituição padrão do cpio e tar que tinha muitas incompatibilidades para padronizar), use cpio -pou em tar -cf - … | tar -xf -vez disso.

Gilles 'SO- parar de ser mau'
fonte